InputStream is = new BufferedInputStream(new FileInputStream("1.jpg"));
image = ImageIO.read(is);
1.jpg是在什么时候进入内存的啊。
帮忙看下 谢谢

解决方案 »

  1.   

    建议看ImageIO类和的源代码,你应该就明白了。
      

  2.   

    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宏转换的 这就是源代码的一小段,根据他的描述,里面都有c的fopen等函数,都是有内存操作的,所以一开始就进入内存了
      

  3.   

    建议看ImageIO类和的源代码,你应该就明白了