A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 寇龙飞 于 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();
复制代码

评分

参与人数 2技术分 +1 黑马币 +20 收起 理由
强强_U00ts + 20 赞一个!
张_涛 + 1 赞一个!

查看全部评分

6 个回复

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

谢谢提点
回复 使用道具 举报
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()方法。

点评

嗯。看了半天源码,各种绕来绕去互相调用,真晕。以后再看吧,只有看源码才能搞清楚了。 FileOutputStream、ByteArrayOutputStream没重写,继承。  发表于 2012-8-29 02:25

评分

参与人数 2技术分 +1 黑马币 +10 收起 理由
张_涛 + 1 赞一个!
寇龙飞 + 10 赞一个!带给我一个思路,查阅api文档,甚至.

查看全部评分

回复 使用道具 举报
你的代码中定义的缓冲区,就不需要要定义一个数组了,把while里的代码改成这样更好
while((count=bufis.read())!=-1)
{
bufos.write(count);
bufos.flush();
}
后面关资源了,不刷也没关系

点评

while循环中不刷没关系? 计算机内存也就1、2G吧,我让它copy个“Java基础视频教程”文件夹,while循环都没走完,就挂了把,最后的close()刷的那点。。。   发表于 2012-8-29 01:38
No! 创建buf缓冲,read(buf, 0, buf.length)、write(buf, 0, count)比read()、write()快太多了,近20倍。 我之前测试过copy4M的mp3文件,分别用31ms、590ms。  发表于 2012-8-29 01:32
回复 使用道具 举报
本帖最后由 周兴华 于 2012-8-28 21:14 编辑

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

点评

I don't think so. API对 类 BufferedOutputStream中flush方法的释义: 刷新此缓冲的输出流。这迫使所有缓冲的输出字节被写出到底层输出流中。  发表于 2012-8-29 01:18
回复 使用道具 举报
黑马杨晨 发表于 2012-8-28 20:45
字节流不需要刷新,字符流需要要刷新(从流中刷到目标位置),

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

再说了,字节流不需要刷新的话api提供这个flush()方法干嘛?
回复 使用道具 举报
字节流不需要刷新,字符流需要要刷新(从流中刷到目标位置),
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马