黑马程序员技术交流社区

标题: IO流小问题 [打印本页]

作者: 郑飞    时间: 2014-8-18 10:27
标题: IO流小问题
本帖最后由 郑飞 于 2014-8-18 14:54 编辑

FielWriter 中的write(buf,0,len) 老毕视频中没用flush()刷新 这个write方法中封装了flush()吗?

作者: pengyu1801    时间: 2014-8-18 10:54
flush()是缓冲区必用神器,不是说每个流必须用
作者: 郑飞    时间: 2014-8-18 11:06
pengyu1801 发表于 2014-8-18 10:54
flush()是缓冲区必用神器,不是说每个流必须用

我就是想知道 FielWriter 中的write(buf,0,len)为什么不用刷新 是不是被封装在哪里了
FileWriter fw = null;
               
                FileReader fr = null;
               
                        fw = new FileWriter("beCopy.java");
                        fr = new FileReader("Copy1.java");
               
       

                char[] buf = new char[1024];
                int len = 0;
               
               
                while ((len = fr.read(buf))!=-1)
                {
                        fw.write(buf,0,len);
                }
                fr.close();
                fw.close();
作者: pengyu1801    时间: 2014-8-18 12:46
郑飞 发表于 2014-8-18 11:06
我就是想知道 FielWriter 中的write(buf,0,len)为什么不用刷新 是不是被封装在哪里了
FileWriter fw  ...

close()方法中自带有刷新功能,所以没写
作者: pengyu1801    时间: 2014-8-18 12:47
pengyu1801 发表于 2014-8-18 12:46
close()方法中自带有刷新功能,所以没写

如果满意送我点黑马币
作者: 郑飞    时间: 2014-8-18 12:56
pengyu1801 发表于 2014-8-18 12:47
如果满意送我点黑马币

while ((len = fr.read(buf))!=-1)
                {
                        fw.write(buf,0,len);
                }
                fr.close();
                fw.close();
我知道close的时候能自动刷新,但是你看这前面不是有while么 一直循环的 按道理不是应该每循环一次就是一个新的buf么 这么多次刷新应该不是最后这个close来完成的吧 哎 我想看源码去了 等下装个myeclipse好看源码
作者: 思如涌泉    时间: 2014-8-18 12:58
close关闭的时候就附带刷新动作了,将数组刷新到文件中
作者: 郑飞    时间: 2014-8-18 13:06
思如涌泉 发表于 2014-8-18 12:58
close关闭的时候就附带刷新动作了,将数组刷新到文件中

每读写一次 不是buf就更新一次吗 读写那么多次 为什么只要最后一次刷新啊
作者: pengyu1801    时间: 2014-8-18 13:29
郑飞 发表于 2014-8-18 12:56
while ((len = fr.read(buf))!=-1)
                {
                        fw.write(buf,0,len);

前面循环的都缓存起来了
作者: Caincxy    时间: 2014-8-18 13:34
学习了啊........
作者: 郑飞    时间: 2014-8-18 13:53
pengyu1801 发表于 2014-8-18 13:29
前面循环的都缓存起来了

好吧 看来我是没弄清楚怎么存进去了 回头我再看看 谢了
作者: 烟海    时间: 2014-8-18 22:50
郑飞 发表于 2014-8-18 13:53
好吧 看来我是没弄清楚怎么存进去了 回头我再看看 谢了

前面循环的。。先相当于临时存到内存一样的容器里面。。。
close之前,全部写入硬盘。。。。
作者: 郑飞    时间: 2014-8-18 23:01
烟海 发表于 2014-8-18 22:50
前面循环的。。先相当于临时存到内存一样的容器里面。。。
close之前,全部写入硬盘。。。。 ...

谢谢 我按这个思路再看看去
作者: liqi    时间: 2014-8-19 11:37
学习了     
作者: 希冀    时间: 2014-8-27 12:21
楼主程序后面是不是用了close方法
作者: 郑飞    时间: 2014-8-27 12:40
希冀 发表于 2014-8-27 12:21
楼主程序后面是不是用了close方法

这个搞明白了 是存到缓冲区了
作者: 冷锋也温柔    时间: 2014-8-31 23:25
没有封装   后面没使用flush()     是因为结尾用close()了   它的作用是刷新内存 后释放资源   它包含了flush的作用
作者: 郑飞    时间: 2014-9-1 02:14
本帖最后由 郑飞 于 2014-9-1 02:17 编辑
冷锋也温柔 发表于 2014-8-31 23:25
没有封装   后面没使用flush()     是因为结尾用close()了   它的作用是刷新内存 后释放资源   它包含 ...

之前看了下BufferedOutputStream中write方法 发现确实是自动刷新的 字符流的还没看 估计也是的 因为缓冲流要用两个数组传递数据的话 肯定不止只传第一次 所以最后的close是不够用的

作者: 黄宝宝    时间: 2014-9-2 12:12
字都打错了
作者: 嘻嘻哈哈嘻嘻    时间: 2014-9-16 16:51
郑飞 发表于 2014-8-18 12:56
while ((len = fr.read(buf))!=-1)
                {
                        fw.write(buf,0,len);

这个只是从文件中读出的buf,然后写到内存中,flush()是内存中写到硬盘中
作者: 嘻嘻哈哈嘻嘻    时间: 2014-9-16 16:54
嘻嘻哈哈嘻嘻 发表于 2014-9-16 16:51
这个只是从文件中读出的buf,然后写到内存中,flush()是内存中写到硬盘中

你还可以试下 把读一个超过你内存的文,不去flush()看看内存会不会爆掉
作者: kid1943    时间: 2014-10-7 09:42
其实查看FileWriter类的所有方法(即包括write方法)都继承自父类OutputStreamWriter。
而查看父类OutputStream的write方法可知无论调用到哪个write方法最终还是调用到,一个叫StreamEncoder类对象se的write方法。

你找到对应的write方法,都可以发现,其会定义一个数组作为缓冲区,当缓冲区写满的时候,就会调用OutputStream(即FileWriter 在构造函数里创建的FileOutputStream对象)的write方法将数据写出。最后不难的出结论,其实FileWriter在将对应的StreamEcoder对象里的缓冲区写满的时候,数据会自动写出去即可以理解为调用了flush(这个可以看下StreamEncoder源码)。
以上是我理解的,楼主还是自己认真看一下StreamEncoder类的源码吧。
作者: kid1943    时间: 2014-10-7 09:48
kid1943 发表于 2014-10-7 09:42
其实查看FileWriter类的所有方法(即包括write方法)都继承自父类OutputStreamWriter。
而查看父类OutputSt ...


      public class StreamEncoder extends Writer
      {
      
          private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
      
          private volatile boolean isOpen = true;
      
          private void ensureOpen() throws IOException {
              if (!isOpen)
                  throw new IOException("Stream closed");
          }
      
      
          public static StreamEncoder forOutputStreamWriter(OutputStream out,
                                                              Object lock,
                                                            String charsetName)
              throws UnsupportedEncodingException
          {
             String csn = charsetName;
              if (csn == null)
                  csn = Charset.defaultCharset().name();
              try {
                  if (Charset.isSupported(csn))
                      return new StreamEncoder(out, lock, Charset.forName(csn));
              } catch (IllegalCharsetNameException x) { }
              throw new UnsupportedEncodingException (csn);
          }
      
          public static StreamEncoder forOutputStreamWriter(OutputStream out,
                                                            Object lock,
                                                            Charset cs)
          {
              return new StreamEncoder(out, lock, cs);
          }
      
          public static StreamEncoder forOutputStreamWriter(OutputStream out,
                                                            Object lock,
                                                            CharsetEncoder enc)
          {
              return new StreamEncoder(out, lock, enc);
          }
      
      
         
          public static StreamEncoder forEncoder(WritableByteChannel ch,
                                                 CharsetEncoder enc,
                                                 int minBufferCap)
          {
              return new StreamEncoder(ch, enc, minBufferCap);
          }
      
     
         public String getEncoding() {
              if (isOpen())
                  return encodingName();
              return null;
          }
     
         public void flushBuffer() throws IOException {
             synchronized (lock) {
                 if (isOpen())
                    implFlushBuffer();
                 else
                     throw new IOException("Stream closed");
             }
        }
     
       public void write(int c) throws IOException {
             char cbuf[] = new char[1];
           cbuf[0] = (char) c;
             write(cbuf, 0, 1);
       }
   
       public void write(char cbuf[], int off, int len) throws IOException {
            synchronized (lock) {
                 ensureOpen();
               if ((off < 0) || (off > cbuf.length) || (len < 0) ||
                   ((off + len) > cbuf.length) || ((off + len) < 0)) {
                    throw new IndexOutOfBoundsException();
                } else if (len == 0) {
                  return;
               }
               implWrite(cbuf, off, len);
            }
       }
   
       public void write(String str, int off, int len) throws IOException {
           /* Check the len before creating a char buffer */
           if (len < 0)
               throw new IndexOutOfBoundsException();
           char cbuf[] = new char[len];
          str.getChars(off, off + len, cbuf, 0);
             write(cbuf, 0, len);
         }
   
         public void flush() throws IOException {
           synchronized (lock) {
                ensureOpen();
                implFlush();
           }
        }
   
        public void close() throws IOException {
            synchronized (lock) {
                 if (!isOpen)
                     return;
                 implClose();
               isOpen = false;
             }
         }
     
         private boolean isOpen() {
             return isOpen;
         }
     
     
     
         private Charset cs;
        private CharsetEncoder encoder;
         private ByteBuffer bb;
   
        
        private final OutputStream out;
         private WritableByteChannel ch;
     
         private boolean haveLeftoverChar = false;
         private char leftoverChar;
         private CharBuffer lcb = null;
   
        private StreamEncoder(OutputStream out, Object lock, Charset cs) {
            this(out, lock,
              cs.newEncoder()
              .onMalformedInput(CodingErrorAction.REPLACE)
             .onUnmappableCharacter(CodingErrorAction.REPLACE));
        }
     
         private StreamEncoder(OutputStream out, Object lock, CharsetEncoder enc) {
                
                
             super(lock);
             this.out = out;
            this.ch = null;
           this.cs = enc.charset();
            this.encoder = enc;
   
             // This path disabled until direct buffers are faster
          if (false && out instanceof FileOutputStream) {
                   ch = ((FileOutputStream)out).getChannel();
             if (ch != null)
                       bb = ByteBuffer.allocateDirect(DEFAULT_BYTE_BUFFER_SIZE);
            }
               if (ch == null) {
             bb = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE);
           }
         }
   
        private StreamEncoder(WritableByteChannel ch, CharsetEncoder enc, int mbc) {
            this.out = null;
           this.ch = ch;
           this.cs = enc.charset();
            this.encoder = enc;
           this.bb = ByteBuffer.allocate(mbc < 0
                                     ? DEFAULT_BYTE_BUFFER_SIZE
                                     : mbc);
       }
   
        private void writeBytes() throws IOException {
            bb.flip();

           int lim = bb.limit();
           int pos = bb.position();
            assert (pos <= lim);
            int rem = (pos <= lim ? lim - pos : 0);
   
               if (rem > 0) {
           if (ch != null) {
                 if (ch.write(bb) != rem)
                     assert false : rem;
            } else {
               out.write(bb.array(), bb.arrayOffset() + pos, rem);
            }
             }
            bb.clear();
          }
   
        private void flushLeftoverChar(CharBuffer cb, boolean endOfInput)
           throws IOException
        {
            if (!haveLeftoverChar && !endOfInput)
                return;
           if (lcb == null)
               lcb = CharBuffer.allocate(2);
           else
              lcb.clear();
           if (haveLeftoverChar)
               lcb.put(leftoverChar);
          if ((cb != null) && cb.hasRemaining())
               lcb.put(cb.get());
          lcb.flip();
           while (lcb.hasRemaining() || endOfInput) {
               CoderResult cr = encoder.encode(lcb, bb, endOfInput);
               if (cr.isUnderflow()) {
                   if (lcb.hasRemaining()) {
                       leftoverChar = lcb.get();
                      if (cb != null && cb.hasRemaining())
                           flushLeftoverChar(cb, endOfInput);
                      return;
                   }
                   break;
               }
             if (cr.isOverflow()) {
                     assert bb.position() > 0;
                    writeBytes();
                    continue;
               }
                cr.throwException();
          }
           haveLeftoverChar = false;
      }
   
                       void implWrite(char cbuf[], int off, int len)
                          throws IOException
                        {
                            CharBuffer cb = CharBuffer.wrap(cbuf, off, len);

                           if (haveLeftoverChar)
                           flushLeftoverChar(cb, false);
                             while (cb.hasRemaining()) {  
                          CoderResult cr = encoder.encode(cb, bb, false);/
                           if (cr.isUnderflow()) {

                              assert (cb.remaining() <= 1) : cb.remaining();、
                              if (cb.remaining() == 1) {
                                   haveLeftoverChar = true;
                                    leftoverChar = cb.get();
                               }
                               break;
                           }
                            if (cr.isOverflow()) {
                               assert bb.position() > 0;
                              writeBytes();
                               continue;
                           }
                           cr.throwException();
                        }
                       
     
         void implFlushBuffer() throws IOException {
             if (bb.position() > 0)
             writeBytes();
         }
   
         void implFlush() throws IOException {
            implFlushBuffer();
            if (out != null)
             out.flush();}
     
        void implClose() throws IOException {
            flushLeftoverChar(null, true);
             try {
                 for (;;) {
                    CoderResult cr = encoder.flush(bb);
                    if (cr.isUnderflow())
                         break;
                    if (cr.isOverflow()) {
                         assert bb.position() > 0;
                        writeBytes();
                         continue;
                     }
                     cr.throwException();
                 }
     
                 if (bb.position() > 0)
                    writeBytes();
                 if (ch != null)
                     ch.close();
                else
                     out.close();
            } catch (IOException x) {
               encoder.reset();
               throw x;
           }
        }
   
        String encodingName() {
            return ((cs instanceof HistoricallyNamedCharset)
                ? ((HistoricallyNamedCharset)cs).historicalName()
                : cs.name());
         }
     }
           

作者: kid1943    时间: 2014-10-7 09:49
kid1943 发表于 2014-10-7 09:42
其实查看FileWriter类的所有方法(即包括write方法)都继承自父类OutputStreamWriter。
而查看父类OutputSt ...

  1.       public class StreamEncoder extends Writer
  2.       {
  3.       
  4.           private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
  5.       
  6.           private volatile boolean isOpen = true;
  7.       
  8.           private void ensureOpen() throws IOException {
  9.               if (!isOpen)
  10.                   throw new IOException("Stream closed");
  11.           }
  12.       
  13.       
  14.           public static StreamEncoder forOutputStreamWriter(OutputStream out,
  15.                                                               Object lock,
  16.                                                             String charsetName)
  17.               throws UnsupportedEncodingException
  18.           {
  19.              String csn = charsetName;
  20.               if (csn == null)
  21.                   csn = Charset.defaultCharset().name();
  22.               try {
  23.                   if (Charset.isSupported(csn))
  24.                       return new StreamEncoder(out, lock, Charset.forName(csn));
  25.               } catch (IllegalCharsetNameException x) { }
  26.               throw new UnsupportedEncodingException (csn);
  27.           }
  28.       
  29.           public static StreamEncoder forOutputStreamWriter(OutputStream out,
  30.                                                             Object lock,
  31.                                                             Charset cs)
  32.           {
  33.               return new StreamEncoder(out, lock, cs);
  34.           }
  35.       
  36.           public static StreamEncoder forOutputStreamWriter(OutputStream out,
  37.                                                             Object lock,
  38.                                                             CharsetEncoder enc)
  39.           {
  40.               return new StreamEncoder(out, lock, enc);
  41.           }
  42.       
  43.       
  44.          
  45.           public static StreamEncoder forEncoder(WritableByteChannel ch,
  46.                                                  CharsetEncoder enc,
  47.                                                  int minBufferCap)
  48.           {
  49.               return new StreamEncoder(ch, enc, minBufferCap);
  50.           }
  51.       
  52.      
  53.          public String getEncoding() {
  54.               if (isOpen())
  55.                   return encodingName();
  56.               return null;
  57.           }
  58.      
  59.          public void flushBuffer() throws IOException {
  60.              synchronized (lock) {
  61.                  if (isOpen())
  62.                     implFlushBuffer();
  63.                  else
  64.                      throw new IOException("Stream closed");
  65.              }
  66.         }
  67.      
  68.        public void write(int c) throws IOException {
  69.              char cbuf[] = new char[1];
  70.            cbuf[0] = (char) c;
  71.              write(cbuf, 0, 1);
  72.        }
  73.    
  74.        public void write(char cbuf[], int off, int len) throws IOException {
  75.             synchronized (lock) {
  76.                  ensureOpen();
  77.                if ((off < 0) || (off > cbuf.length) || (len < 0) ||
  78.                    ((off + len) > cbuf.length) || ((off + len) < 0)) {
  79.                     throw new IndexOutOfBoundsException();
  80.                 } else if (len == 0) {
  81.                   return;
  82.                }
  83.                implWrite(cbuf, off, len);
  84.             }
  85.        }
  86.    
  87.        public void write(String str, int off, int len) throws IOException {
  88.            /* Check the len before creating a char buffer */
  89.            if (len < 0)
  90.                throw new IndexOutOfBoundsException();
  91.            char cbuf[] = new char[len];
  92.           str.getChars(off, off + len, cbuf, 0);
  93.              write(cbuf, 0, len);
  94.          }
  95.    
  96.          public void flush() throws IOException {
  97.            synchronized (lock) {
  98.                 ensureOpen();
  99.                 implFlush();
  100.            }
  101.         }
  102.    
  103.         public void close() throws IOException {
  104.             synchronized (lock) {
  105.                  if (!isOpen)
  106.                      return;
  107.                  implClose();
  108.                isOpen = false;
  109.              }
  110.          }
  111.      
  112.          private boolean isOpen() {
  113.              return isOpen;
  114.          }
  115.      
  116.      
  117.      
  118.          private Charset cs;
  119.         private CharsetEncoder encoder;
  120.          private ByteBuffer bb;
  121.    
  122.         
  123.         private final OutputStream out;
  124.          private WritableByteChannel ch;
  125.      
  126.          private boolean haveLeftoverChar = false;
  127.          private char leftoverChar;
  128.          private CharBuffer lcb = null;
  129.    
  130.         private StreamEncoder(OutputStream out, Object lock, Charset cs) {
  131.             this(out, lock,
  132.               cs.newEncoder()
  133.               .onMalformedInput(CodingErrorAction.REPLACE)
  134.              .onUnmappableCharacter(CodingErrorAction.REPLACE));
  135.         }
  136.      
  137.          private StreamEncoder(OutputStream out, Object lock, CharsetEncoder enc) {
  138.                 
  139.                 
  140.              super(lock);
  141.              this.out = out;
  142.             this.ch = null;
  143.            this.cs = enc.charset();
  144.             this.encoder = enc;
  145.    
  146.              // This path disabled until direct buffers are faster
  147.           if (false && out instanceof FileOutputStream) {
  148.                    ch = ((FileOutputStream)out).getChannel();
  149.              if (ch != null)
  150.                        bb = ByteBuffer.allocateDirect(DEFAULT_BYTE_BUFFER_SIZE);
  151.             }
  152.                if (ch == null) {
  153.              bb = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE);
  154.            }
  155.          }
  156.    
  157.         private StreamEncoder(WritableByteChannel ch, CharsetEncoder enc, int mbc) {
  158.             this.out = null;
  159.            this.ch = ch;
  160.            this.cs = enc.charset();
  161.             this.encoder = enc;
  162.            this.bb = ByteBuffer.allocate(mbc < 0
  163.                                      ? DEFAULT_BYTE_BUFFER_SIZE
  164.                                      : mbc);
  165.        }
  166.    
  167.         private void writeBytes() throws IOException {
  168.             bb.flip();

  169.            int lim = bb.limit();
  170.            int pos = bb.position();
  171.             assert (pos <= lim);
  172.             int rem = (pos <= lim ? lim - pos : 0);
  173.    
  174.                if (rem > 0) {
  175.            if (ch != null) {
  176.                  if (ch.write(bb) != rem)
  177.                      assert false : rem;
  178.             } else {
  179.                out.write(bb.array(), bb.arrayOffset() + pos, rem);
  180.             }
  181.              }
  182.             bb.clear();
  183.           }
  184.    
  185.         private void flushLeftoverChar(CharBuffer cb, boolean endOfInput)
  186.            throws IOException
  187.         {
  188.             if (!haveLeftoverChar && !endOfInput)
  189.                 return;
  190.            if (lcb == null)
  191.                lcb = CharBuffer.allocate(2);
  192.            else
  193.               lcb.clear();
  194.            if (haveLeftoverChar)
  195.                lcb.put(leftoverChar);
  196.           if ((cb != null) && cb.hasRemaining())
  197.                lcb.put(cb.get());
  198.           lcb.flip();
  199.            while (lcb.hasRemaining() || endOfInput) {
  200.                CoderResult cr = encoder.encode(lcb, bb, endOfInput);
  201.                if (cr.isUnderflow()) {
  202.                    if (lcb.hasRemaining()) {
  203.                        leftoverChar = lcb.get();
  204.                       if (cb != null && cb.hasRemaining())
  205.                            flushLeftoverChar(cb, endOfInput);
  206.                       return;
  207.                    }
  208.                    break;
  209.                }
  210.              if (cr.isOverflow()) {
  211.                      assert bb.position() > 0;
  212.                     writeBytes();
  213.                     continue;
  214.                }
  215.                 cr.throwException();
  216.           }
  217.            haveLeftoverChar = false;
  218.       }
  219.    
  220.                        void implWrite(char cbuf[], int off, int len)
  221.                           throws IOException
  222.                         {
  223.                             CharBuffer cb = CharBuffer.wrap(cbuf, off, len);

  224.                            if (haveLeftoverChar)
  225.                            flushLeftoverChar(cb, false);
  226.                              while (cb.hasRemaining()) {  
  227.                           CoderResult cr = encoder.encode(cb, bb, false);/
  228.                            if (cr.isUnderflow()) {

  229.                               assert (cb.remaining() <= 1) : cb.remaining();、
  230.                               if (cb.remaining() == 1) {
  231.                                    haveLeftoverChar = true;
  232.                                     leftoverChar = cb.get();
  233.                                }
  234.                                break;
  235.                            }
  236.                             if (cr.isOverflow()) {
  237.                                assert bb.position() > 0;
  238.                               writeBytes();
  239.                                continue;
  240.                            }
  241.                            cr.throwException();
  242.                         }
  243.                        
  244.      
  245.          void implFlushBuffer() throws IOException {
  246.              if (bb.position() > 0)
  247.              writeBytes();
  248.          }
  249.    
  250.          void implFlush() throws IOException {
  251.             implFlushBuffer();
  252.             if (out != null)
  253.              out.flush();}
  254.      
  255.         void implClose() throws IOException {
  256.             flushLeftoverChar(null, true);
  257.              try {
  258.                  for (;;) {
  259.                     CoderResult cr = encoder.flush(bb);
  260.                     if (cr.isUnderflow())
  261.                          break;
  262.                     if (cr.isOverflow()) {
  263.                          assert bb.position() > 0;
  264.                         writeBytes();
  265.                          continue;
  266.                      }
  267.                      cr.throwException();
  268.                  }
  269.      
  270.                  if (bb.position() > 0)
  271.                     writeBytes();
  272.                  if (ch != null)
  273.                      ch.close();
  274.                 else
  275.                      out.close();
  276.             } catch (IOException x) {
  277.                encoder.reset();
  278.                throw x;
  279.            }
  280.         }
  281.    
  282.         String encodingName() {
  283.             return ((cs instanceof HistoricallyNamedCharset)
  284.                 ? ((HistoricallyNamedCharset)cs).historicalName()
  285.                 : cs.name());
  286.          }
  287.      }
  288. 这是StreamEncoder源码      
复制代码

作者: 郑飞    时间: 2014-10-7 10:47
kid1943 发表于 2014-10-7 09:42
其实查看FileWriter类的所有方法(即包括write方法)都继承自父类OutputStreamWriter。
而查看父类OutputSt ...

后来是看了源码 确实是封装了flush对象 谢谢...




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