黑马程序员技术交流社区

标题: FileInputStream里的read()方法是怎么谁是? [打印本页]

作者: 嘿嘿小学徒    时间: 2012-12-29 22:11
标题: FileInputStream里的read()方法是怎么谁是?
本帖最后由 dustookk 于 2012-12-31 09:28 编辑

我查看了下源码 , 是这么写的:
  1.      /**
  2.      * Reads a byte of data from this input stream. This method blocks
  3.      * if no input is yet available.
  4.      *
  5.      * @return     the next byte of data, or <code>-1</code> if the end of the
  6.      *             file is reached.
  7.      * @exception  IOException  if an I/O error occurs.
  8.      */
  9. public native int read() throws IOException;
复制代码


然后在ctrl+click  点红色的read就没反应了

这不科学啊!   没有实现方式!


其实我就像知道和BufferedInputStream的read() 和它的read()相比 是怎么加入"缓存"的 ...- -||


如果就read()方法来说, 为什么要多此一举定义一个BufferedInputStream呢? 有什么好处?
作者: 王玮    时间: 2012-12-29 22:57
  1. private void fill() throws IOException {
  2.         byte[] buffer = getBufIfOpen();
  3.         if (markpos < 0)
  4.             pos = 0;                /* no mark: throw away the buffer */
  5.         else if (pos >= buffer.length)        /* no room left in buffer */
  6.             if (markpos > 0) {        /* can throw away early part of the buffer */
  7.                 int sz = pos - markpos;
  8.                 System.arraycopy(buffer, markpos, buffer, 0, sz);
  9.                 pos = sz;
  10.                 markpos = 0;
  11.             } else if (buffer.length >= marklimit) {
  12.                 markpos = -1;        /* buffer got too big, invalidate mark */
  13.                 pos = 0;        /* drop buffer contents */
  14.             } else {                /* grow buffer */
  15.                 int nsz = pos * 2;
  16.                 if (nsz > marklimit)
  17.                     nsz = marklimit;
  18.                 byte nbuf[] = new byte[nsz];
  19.                 System.arraycopy(buffer, 0, nbuf, 0, pos);
  20.                 if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
  21.                     // Can't replace buf if there was an async close.
  22.                     // Note: This would need to be changed if fill()
  23.                     // is ever made accessible to multiple threads.
  24.                     // But for now, the only way CAS can fail is via close.
  25.                     // assert buf == null;
  26.                     throw new IOException("Stream closed");
  27.                 }
  28.                 buffer = nbuf;
  29.             }
  30.         count = pos;
  31.         int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
  32.         if (n > 0)
  33.             count = n + pos;
  34.     }

  35.     /**
  36.      * See
  37.      * the general contract of the <code>read</code>
  38.      * method of <code>InputStream</code>.
  39.      *
  40.      * @return     the next byte of data, or <code>-1</code> if the end of the
  41.      *             stream is reached.
  42.      * @exception  IOException  if this input stream has been closed by
  43.      *                                invoking its {@link #close()} method,
  44.      *                                or an I/O error occurs.
  45.      * @see        java.io.FilterInputStream#in
  46.      */
  47.     public synchronized int read() throws IOException {
  48.         if (pos >= count) {
  49.             fill();
  50.             if (pos >= count)
  51.                 return -1;
  52.         }
  53.         return getBufIfOpen()[pos++] & 0xff;
  54.     }
复制代码

作者: 嘿嘿小学徒    时间: 2012-12-29 23:35
王玮 发表于 2012-12-29 22:57

谢谢你的回复!

可这是fill()方法 , read()中调用的它么?  怎么哪儿都没说呢?
作者: 清水    时间: 2012-12-29 23:49
BufferedInputStream 事先读好了一段在内存中,read一次,pos就往前移一。当pos移到末尾了,那么BufferedInputStream再从硬盘上抓一段过来。
虽然此read和彼read写法一样,但是实现原理不同。
作者: 嘿嘿小学徒    时间: 2012-12-30 00:14
清冰 发表于 2012-12-29 23:49
BufferedInputStream 事先读好了一段在内存中,read一次,pos就往前移一。当pos移到末尾了,那么BufferedIn ...

哦.......我试试自己实现一下BufferedInputStream这个类!    谢谢!
作者: yuchen208    时间: 2012-12-30 10:27
加载到缓存中达到一定大小在输出流中结束之前flush
作者: 黄锦成    时间: 2012-12-30 16:55
用个复制文件的例子来解释一下:
使用FileInputStream复制:文本=>内存=>目的文本,每次都要从文本中读取数据,经过内存,再到目的文本,这个性能是比较低下的。

使用BufferedInputStream复制:文本=>读取缓冲=>内存=>输出缓冲=>目的文本,这个呢,我们主要是走“读取缓冲=>内存=>输出缓冲=>目的文本”这一步,而且“读取缓冲=>内存=>输出缓冲”这三个都是在内存中的,性能是比较高的。

作者: zshzj    时间: 2012-12-31 06:45
这里最后调用的是dll里面的代码,你是看不见的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2