黑马程序员技术交流社区
标题:
关于IO流的一点疑问~
[打印本页]
作者:
马姗姗
时间:
2014-1-6 13:53
标题:
关于IO流的一点疑问~
本帖最后由 马姗姗 于 2014-1-6 21:59 编辑
FileWriter 是使用“流”,直接将数据写入到具体物理设备中,那么为什么write方法后还要flush刷新该流的缓冲?
既然“流”就是缓冲,那么BufferedWriter缓冲有什么不一样吗?BufferedWriter是怎么提高效率的?
作者:
几番意难相付
时间:
2014-1-6 14:18
write方法并不是直接将数据写入到存储介质中 而是写入到内存中的缓冲区中 使用flush方法后 才会将内存缓冲区中的数据写进存储介质
filewrite写入文件的方式是从源文件中读取一个字节 再向内存写入一个字节
bufferedwriter是从源文件读取一定的字节到字节数组中 当该数组的容量满了以后 才将数组中的数据写入到内存的缓冲区里。
打个比方 这是毕姥爷的教程里的比方:
你i想喝水 饮水机坏了 只能一滴一滴的滴水 如果没有缓冲区 只能饮水机滴一滴 你喝一滴
而有了缓冲区 就相当于拿了个杯子放在饮水机的出水口那 等杯子的水满了 你才去喝杯子里的水
作者:
悠然的我
时间:
2014-1-6 14:49
同学,首先“流”不一定都带缓冲区的,不能认为“流”就是缓冲。只有字符流,也就是Reader和Writer才带缓冲区的,字节流steam直接就写入、读取,不带缓冲区的。其二,FileWriter既然是字符流,自然是有缓冲区的,查API,FileWriter是OutputStreamWriter的子类,该类是有缓冲区的,实现了flush。
查阅OutputStreamWriter的描述:我们找到这样一段话:
每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器
是不是可以这么理解,缓冲是分为两个阶段的,OutputStreamWriter在write 和底层的字节输出之间建立了缓冲,而BufferedWriter 则在调用write之前就建立了缓冲,从而避免了频繁调用write,而是攒够数据一次性的write。恩,我就能理解到这里了,坐等高手全面解答。
作者:
L_t
时间:
2014-1-6 20:48
package cn04;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 需求:把d:\\爸爸去哪儿.mp3复制到项目路径下x.mp3(x=1,2,3,4)
*
* @author Administrator
*
* 基本字节流一次读写一个字节:耗时:52194毫秒
* 基本字节流一次读写一个字节数组:耗时:177毫秒
* 高效字节流一次读写一个字节:耗时:27985毫秒
* 高效字节流一次读写一个字节数组:耗时:53毫秒
*/
public class copyMp3Test {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
// show1();
// show2();
// show3();
show4();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "毫秒");
}
private static void show4() throws IOException {
// 高效字节流一次读写一个字节数组
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"d:\\爸爸去哪儿.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("4.mp3"));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}
// 释放资源
bos.close();
bis.close();
}
private static void show3() throws IOException {
// 高效字节流一次读写一个字节
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"d:\\爸爸去哪儿.mp3"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("3.mp3"));
int by = 0;
while ((by = bis.read()) != -1) {
bos.write(by);
bos.flush();
}
// 释放资源
bos.close();
bis.close();
}
private static void show2() throws IOException {
// 基本字节流一次读写一个字节数组
FileInputStream fis = new FileInputStream("d:\\爸爸去哪儿.mp3");
FileOutputStream fos = new FileOutputStream("2.mp3");
byte[] bys = new byte[1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
fos.write(bys, 0, len);
fos.flush();
}
// 释放资源
fos.close();
fis.close();
}
private static void show1() throws IOException {
// 基本字节流一次读写一个字节
FileInputStream fis = new FileInputStream("d:\\爸爸去哪儿.mp3");
FileOutputStream fos = new FileOutputStream("1.mp3");
int by = 0;
while ((by = fis.read()) != -1) {
fos.write(by);
fos.flush();
}
// 释放资源
fos.close();
fis.close();
}
}
BufferedWriter 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。 该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2