最近做一个很简单的函数,要两个返回值,我打算有一个类封装一下返回,后来领导要求使用StringBuilder返回,不用StringBuffer,因为局部变量StringBuffer最后还是要编译为StringBuilder,因为StringBuilder没有任何同步。
问了一下大家的看法,风南说InputStream 的int read(byte[] b) 从输入流中读取一定数量的字节并将其存储在缓冲区数组 b 中,也是类似的,看来有必要研究一下IO了。
InputStream类中重要的函数,只有一个抽象的有用,
public abstract int read() throws IOException;
其他两个read的意义不大。
public int read(byte b[], int off, int len) throws IOException 和
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
下面看它的子类FileInputStream的实现,
/* File Descriptor - handle to the open file */
private FileDescriptor fd;
这个很重要,这是文件句柄,C语言使用fopen函数的都知道。
/**
* Opens the specified file for reading.
* @param name the name of the file
*/
private native void open(String name) throws FileNotFoundException;
/**
* Reads a byte of data from this input stream. This method blocks
* if no input is yet available.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* file is reached.
* @exception IOException if an I/O error occurs.
*/
public native int read() throws IOException;
/**
* Reads a subarray as a sequence of bytes.
* @param b the data to be written
* @param off the start offset in the data
* @param len the number of bytes that are written
* @exception IOException If an I/O error has occurred.
*/
private native int readBytes(byte b[], int off, int len) throws IOException;
子类修改了父的实现
/**
* Reads up to <code>b.length</code> bytes of data from this input
* stream into an array of bytes. This method blocks until some input
* is available.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[]) throws IOException {
return readBytes(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. If <code>len</code> is not zero, the method
* blocks until some input is available; otherwise, no
* bytes are read and <code>0</code> is returned.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array <code>b</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the file has been reached.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
return readBytes(b, off, len);
}
看出readBytes是关键的所在,windows的native code中只有
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_close0(JNIEnv *env, jobject this) {
handleClose(env, this, fis_fd);
}
是平台相关的。
其他的在share中
FileInputStream.c代码
jfieldID fis_fd; /* id for jobject 'fd' in java.io.FileInputStream */
/**************************************************************
* static methods to store field ID's in initializers
*/
得到fd的值,这个很重要
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_initIDs(JNIEnv *env, jclass fdClass) {
fis_fd = (*env)->GetFieldID(env, fdClass, "fd", "Ljava/io/FileDescriptor;");
}
/**************************************************************
* Input stream
*/
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {
fileOpen(env, this, path, fis_fd, O_RDONLY);
}
JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_read(JNIEnv *env, jobject this) {
return readSingle(env, this, fis_fd);
}
JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_readBytes(JNIEnv *env, jobject this,
jbyteArray bytes, jint off, jint len) {
return readBytes(env, this, bytes, off, len, fis_fd);
}
JNIEXPORT jlong JNICALL
Java_java_io_FileInputStream_skip(JNIEnv *env, jobject this, jlong toSkip) {
jlong cur = jlong_zero;
jlong end = jlong_zero;
FD fd = GET_FD(this, fis_fd);
if ((cur = IO_Lseek(fd, (jlong)0, (jint)SEEK_CUR)) == -1) {
JNU_ThrowIOExceptionWithLastError(env, "Seek error");
} else if ((end = IO_Lseek(fd, toSkip, (jint)SEEK_CUR)) == -1) {
JNU_ThrowIOExceptionWithLastError(env, "Seek error");
}
return (end - cur);
}
JNIEXPORT jint JNICALL
Java_java_io_FileInputStream_available(JNIEnv *env, jobject this) {
jlong ret;
FD fd = GET_FD(this, fis_fd);
if (IO_Available(fd, &ret)) {
if (ret > INT_MAX) {
ret = (jlong) INT_MAX;
}
return jlong_to_jint(ret);
}
JNU_ThrowIOExceptionWithLastError(env, NULL);
return 0;
}
主要是readBytes的实现,打开io_util.c文件
/* IO helper functions */
int
readSingle(JNIEnv *env, jobject this, jfieldID fid) {
int nread;
char ret;
FD fd = GET_FD(this, fid);
nread = IO_Read(fd, &ret, 1);
if (nread == 0) { /* EOF */
return -1;
} else if (nread == JVM_IO_ERR) { /* error */
JNU_ThrowIOExceptionWithLastError(env, "Read error");
} else if (nread == JVM_IO_INTR) {
JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
}
return ret & 0xFF;
}
/* The maximum size of a stack-allocated buffer.
*/
#define BUF_SIZE 8192
int
readBytes(JNIEnv *env, jobject this, jbyteArray bytes,
jint off, jint len, jfieldID fid)
{
int nread, datalen;
char stackBuf[BUF_SIZE];
char *buf = 0;
FD fd;
if (IS_NULL(bytes)) {
JNU_ThrowNullPointerException(env, 0);
return -1;
}
datalen = (*env)->GetArrayLength(env, bytes);
if ((off < 0) || (off > datalen) ||
(len < 0) || ((off + len) > datalen) || ((off + len) < 0)) {
JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", 0);
return -1;
}
if (len == 0) {
return 0;
} else if (len > BUF_SIZE) {
buf = malloc(len);
if (buf == 0) {
JNU_ThrowOutOfMemoryError(env, 0);
return 0;
}
} else {
buf = stackBuf;
}
fd = GET_FD(this, fid);
nread = IO_Read(fd, buf, len);
if (nread > 0) {
(*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
} else if (nread == JVM_IO_ERR) {
JNU_ThrowIOExceptionWithLastError(env, "Read error");
} else if (nread == JVM_IO_INTR) { /* EOF */
JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
} else { /* EOF */
nread = -1;
}
if (buf != stackBuf) {
free(buf);
}
return nread;
}
注意IO_Read在io_util_md.h做了手脚的,
#define IO_Read JVM_Read
其实就是JVM_Read,JVM_Read在hotspot源码中定义的
//%note jvm_r6
return (jint)hpi::read(fd, buf, nbytes);
hpi定义了大量的函数
// HPI_FileInterface
static inline char* native_path(char *path);
static inline int file_type(const char *path);
static inline int open(const char *name, int mode, int perm);
static inline int close(int fd);
static inline jlong lseek(int fd, jlong off, int whence);
static inline int ftruncate(int fd, jlong length);
static inline int fsync(int fd);
static inline int available(int fd, jlong *bytes);
static inline size_t read(int fd, void *buf, unsigned int nBytes);
static inline size_t write(int fd, const void *buf, unsigned int nBytes);
static inline int fsize(int fd, jlong *size);
这就是和平台相关的代码了。window下通过HPIDECL宏转换的
分享到:
相关推荐
InputStream in = new FileInputStream("D:\\Client"); byte[] buf = new byte[1024*1024]; int len; ByteArrayOutputStream bufOut = new ByteArrayOutputStream(); while (true) { len = in.read(buf); if ...
import java.io.FileInputStream; import java.util.Properties; public class ReadConfigation{ /** * 属性文件全名 */ private static final String PFILE ="Config.properties"; /** * 对应于...
fis = new FileInputStream("E:\\程序\\java\\1.AVI"); buf = new byte[1024]; long streamnum=fis.available(); int c=(int) Math.floor(streamnum/1024); patch=(int)streamnum24; Sduct();//发出尾数 if(c...
【项目源码】-java学生管理系统 package appstu; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.util....
import java.io.*; import java.util.*; import java.util.zip.Adler32; import java.util.zip.CheckedInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip....
源码 JavaIO ##JavaIO基础面试题 1. 什么是IO 它是一种数据的流从源头到目的地。比如文件拷贝,输入流和输出流都包括了。输入流是从文件中读取数据到存储到进程(process)中,输出流是从进程中读取数据然后写入到目标...
NULL 博文链接:https://coffeesweet.iteye.com/blog/812263
13.4.1 FileInputStream和FileOutputStream336 13.4.2 FileReader和FileWriter338 13.5 缓冲流340 13.6 转换流341 13.7 数据流342 13.8 打印流344 13.9 对象流345 13.9.1 序列化和反序列化操作345 13.9.2 序列化的...
Java将多张图片合成为一张,类似于PhotoShop中的合成图片,将两张图片合成输出为一张JPG,两幅图像叠加在一起,这是个比较基础的Java图像合成的例子。在JAVA中实现图片合成,本例的实现核心代码如下: InputStream...
Java生成 数字证书源码,从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂,获取证书,请查看以下相关代码: //生成文件输入流,输入文件为c:/mycert.cer ...
1 从Excel文件读取数据表 ... InputStream is = new FileInputStream(sourcefile); jxl.Workbook rwb = Workbook.getWorkbook(is); } catch (Exception e) { e.printStackTrace(); }
* 或者 InputStream in = new FileInputStream(String fileName);//读取文件中的数据。可以看出 * FileInputStream 为InputStream的子类。 * * 主要方法:int read();//读取单个字符。 int read(char []cbuf);/...
Java压缩中文名的文件,大家都知道Java处理英文名的文件很强大,但是处理起中文名那可是比较麻烦了,需要经过很多步骤,这个例子可以告诉你如何简易的处理中文文件名的文件,以压缩中文文件名的文件为例。...
Java Zip算法压缩多个文件的例子,具体的实现原理是:先打开文件并读取,然后利用ZipEntry实例化待压缩的条目列表,将ZIP条目列表写入输出流,从源文件得到文件输入流,写入缓冲数据等。相关代码: ...
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; ...
文件流操作:使用Java的文件输入输出流(FileInputStream、FileOutputStream)读取和写入文件内容。 多线程处理:通过多线程实现并发处理多个文件传输请求,提高传输效率。 异常处理:处理网络异常、文件读写异常等...
java.io.FileInputStream fis = new java.io.FileInputStream( new java.io.File("d:\\数据库.zip")); // 转换成网络输出流 java.net.ServerSocket ss = new java.net.ServerSocket(9000); java.net....
5.import java.io.FileInputStream; 6.import javax.imageio.ImageIO; , 而且往往几百行,手动花上几分钟去删除很是麻烦,而且最后代码是不是我们想要的也很难说 ,由于经常碰上这种事,干脆花个时间去写出来,...
FileInputStream fin=new FileInputStream(fileIn); //得到文件输入流 FileOutputStream fout=new FileOutputStream(fileOut); //得到文件输出流 byte[] bytes=new byte[1024]; //初始化字节数组,用于...