`
liuchen_good
  • 浏览: 4913 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

java源码FileInputStream

阅读更多
最近做一个很简单的函数,要两个返回值,我打算有一个类封装一下返回,后来领导要求使用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宏转换的
分享到:
评论

相关推荐

    TCP并发上传——java源码

    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 ...

    Java读取资源文件工具类--ReadConfigation(java源码)

    import java.io.FileInputStream; import java.util.Properties; public class ReadConfigation{ /** * 属性文件全名 */ private static final String PFILE ="Config.properties"; /** * 对应于...

    桌面管家源码(java)

    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学生管理系统

    【项目源码】-java学生管理系统 package appstu; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.util....

    java压缩文件源码--ZipUtils

    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....

    java7源码-JavaIO:JavaIO

    源码 JavaIO ##JavaIO基础面试题 1. 什么是IO 它是一种数据的流从源头到目的地。比如文件拷贝,输入流和输出流都包括了。输入流是从文件中读取数据到存储到进程(process)中,输出流是从进程中读取数据然后写入到目标...

    有关java上传和File以及FileInputStream的区别

    NULL 博文链接:https://coffeesweet.iteye.com/blog/812263

    java基础案例与开发详解案例源码全

    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将多张图片合成为一张图像.rar

    Java将多张图片合成为一张,类似于PhotoShop中的合成图片,将两张图片合成输出为一张JPG,两幅图像叠加在一起,这是个比较基础的Java图像合成的例子。在JAVA中实现图片合成,本例的实现核心代码如下:  InputStream...

    Java从文件中读取数字证书.rar

    Java生成 数字证书源码,从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂,获取证书,请查看以下相关代码:  //生成文件输入流,输入文件为c:/mycert.cer  ...

    java_对excel_的操作源码(有备无患)

    1 从Excel文件读取数据表 ... InputStream is = new FileInputStream(sourcefile); jxl.Workbook rwb = Workbook.getWorkbook(is); } catch (Exception e) { e.printStackTrace(); }

    Java文件读写操作函数实现

    * 或者 InputStream in = new FileInputStream(String fileName);//读取文件中的数据。可以看出 * FileInputStream 为InputStream的子类。 * * 主要方法:int read();//读取单个字符。 int read(char []cbuf);/...

    Java压缩带有中文名的文件.rar

    Java压缩中文名的文件,大家都知道Java处理英文名的文件很强大,但是处理起中文名那可是比较麻烦了,需要经过很多步骤,这个例子可以告诉你如何简易的处理中文文件名的文件,以压缩中文文件名的文件为例。...

    Java Zip算法压缩多个文件的例子.rar

    Java Zip算法压缩多个文件的例子,具体的实现原理是:先打开文件并读取,然后利用ZipEntry实例化待压缩的条目列表,将ZIP条目列表写入输出流,从源文件得到文件输入流,写入缓冲数据等。相关代码:  ...

    Struts Updownload 源码

    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文件传输的实现.rar

    文件流操作:使用Java的文件输入输出流(FileInputStream、FileOutputStream)读取和写入文件内容。 多线程处理:通过多线程实现并发处理多个文件传输请求,提高传输效率。 异常处理:处理网络异常、文件读写异常等...

    计算机网络实验报告 获取MAC socket通信

    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; , 而且往往几百行,手动花上几分钟去删除很是麻烦,而且最后代码是不是我们想要的也很难说 ,由于经常碰上这种事,干脆花个时间去写出来,...

    Java仿Windows 窗口化复制文件功能.rar

      FileInputStream fin=new FileInputStream(fileIn); //得到文件输入流   FileOutputStream fout=new FileOutputStream(fileOut); //得到文件输出流   byte[] bytes=new byte[1024]; //初始化字节数组,用于...

Global site tag (gtag.js) - Google Analytics