黑马程序员技术交流社区

标题: 字节输出流flush刷新与不刷新的区别。求原理。 [打印本页]

作者: 寇龙飞    时间: 2012-8-28 20:42
标题: 字节输出流flush刷新与不刷新的区别。求原理。
本帖最后由 寇龙飞 于 2012-8-29 01:25 编辑
  1. public static void copyFile(String from, String dest) throws Exception {
  2.                
  3.                 File ff = new File(from);//目标文件
  4.                 File ft = new File(dest);//目的文件
  5.                
  6.                 FileInputStream fis = new FileInputStream(ff);
  7.                 FileOutputStream fos = new FileOutputStream(ft);
  8.                
  9.                 BufferedInputStream bufis =new BufferedInputStream(fis);
  10.                 BufferedOutputStream bufos =new BufferedOutputStream(fos);
  11.                
  12.                 byte[] buf = new byte[1024*4];
  13.                 int count = 0;
  14.                 while((count=bufis.read(buf, 0, buf.length))!=-1) {
  15.                         bufos.write(buf, 0, count);
  16.                         //bufos.flush();//需不需要刷新?
复制代码
这是我一个复制文件程序的部分代码。看代码注视部分。求解。

之前贴的代码while循环都不完整,失误,重贴个。
  1. BufferedInputStream bufis =new BufferedInputStream(fis);
  2.                 BufferedOutputStream bufos =new BufferedOutputStream(fos);
  3.                
  4.                 byte[] buf = new byte[1024*4];
  5.                 int count = 0;
  6.                 while((count=bufis.read(buf, 0, buf.length))!=-1) {
  7.                         bufos.write(buf, 0, count);
  8.                         //bufos.flush();//需不需要刷新?
  9.                 }

  10.                 bufis.close();
  11.                 bufos.close();
复制代码

作者: 黑马杨晨    时间: 2012-8-28 20:45
字节流不需要刷新,字符流需要要刷新(从流中刷到目标位置),
作者: 寇龙飞    时间: 2012-8-28 21:02
黑马杨晨 发表于 2012-8-28 20:45
字节流不需要刷新,字符流需要要刷新(从流中刷到目标位置),

字符流、字节流,不都是缓存内存中,然后刷出去么?

再说了,字节流不需要刷新的话api提供这个flush()方法干嘛?
作者: 周兴华    时间: 2012-8-28 21:12
本帖最后由 周兴华 于 2012-8-28 21:14 编辑

1、字节流写入流中的单元是字节单元,当流关闭时可以直接传到目的地中去。
2、字符流写入流中的单元是字符单元,如果要写入到目的地(比如一个文本文件)中,必须是以字节形式才能写入。
所以流中的字符单元需要先经过编码后才能写入目的地。而刷新的功能就是将流中字符单元先编码成字节数据后再写入目的地。
以上,是我的理解,不知道对不对。
我觉得关键就在于我们系统中最终存储的数据还是字节数据,在我们打开一个文本文件看到是字符时,其实都是记事本软件先经过解码后再输出给我们看到的。

作者: 王金科    时间: 2012-8-28 21:16
你的代码中定义的缓冲区,就不需要要定义一个数组了,把while里的代码改成这样更好
while((count=bufis.read())!=-1)
{
bufos.write(count);
bufos.flush();
}
后面关资源了,不刷也没关系
作者: 任文杰    时间: 2012-8-28 21:47
BufferedOutputStream此类继承自java.io.FilterOutputStream并重写了父类的flush()方法,所以最好在写完数据后调用一下flush()方法。此类的flush()方法如下:
  1.     public synchronized void flush() throws IOException {  
  2.             flushBuffer();  
  3.         out.flush();  
  4.     }  

  5.     /** Flush the internal buffer */  
  6.     private void flushBuffer() throws IOException {  
  7.         if (count > 0) {  
  8.      out.write(buf, 0, count);  
  9.      count = 0;  
  10.         }  
  11.     }  
复制代码
通过查看文档,我发现FileOutputStream、ByteArrayOutputStream这两个输出流虽然重写父类的flush()方法,仅是调用父类的flush()方法:
  1.     public void flush() throws IOException {  
  2.         out.flush();  
  3.     }  
复制代码
而父类的flush()方法什么都没有做,
  1.     public void flush() throws IOException {  
  2.     }  
复制代码
所以诸如这些输出流类可以在写完数据时不调用flush()方法。

不过,话又说回来,一般用完IO流之后(如果你有一个好的习惯)我们都会去调用close()方法,看源码可以知道该方法也是调用相对应的flush()方法。所以,大多数情况下你不必要担心。这里提醒一下,如果你的文件读写没有达到预期目的,十之八九是因为你没有调用flush()或者close()方法。

作者: 王金科    时间: 2012-8-29 02:17
王金科 发表于 2012-8-28 21:16
你的代码中定义的缓冲区,就不需要要定义一个数组了,把while里的代码改成这样更好
while((count=bufis.read( ...

谢谢提点




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