总结自java零基础教学最新入门视频(1-8 File类与IO流)
《Java开发实战经典 第二版》
Java IO流学习总结三:缓冲流-BufferedInputStream、BufferedOutputStream
缓冲流
缓冲流又叫高效流,是对4个FileXXX基本流的增强。
原理:在创建缓冲流时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,提高读写效率。
字节缓冲流:BufferedInputStream,BufferedOutputStream
字符缓冲流:BufferedWriter,BufferedReader
字节缓冲流
- BufferedOutputStream
继承自FilterOutputStream,FilterOutputStream继承自OutputStream,因此有父类的一些方法方法。
其成员变量有两个值得关注:
//缓冲区
protected byte buf[];
//已用的缓冲区字节数
protected int count;
构造方法:
//默认缓冲区,8192个字节
public BufferedOutputStream(OutputStream out);
//指定缓冲区大小,size字节
public BufferedOutputStream(OutputStream out, int size);
以增强FileOutputStream为例
//一
public static void main(String[] args) throws IOException {
File file = new File("D:\\Willow.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file));
bufferedOutputStream.write("Today is new.".getBytes());
//必须调用flush后才写入到文件,否则在缓冲区中,调用close会自动调用flush
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
//二
public static void main(String[] args) {
File file = new File("D:\\Willow.txt");
//这样try,会自动关闭资源,也就是会自动flush,因此可写成功
try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file))) {
bufferedOutputStream.write("Today is new.".getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
注意:
当缓冲区满或者调用close时,会自动flush缓冲区内容到文件中。
关闭缓冲流就可以,字节流也会被关闭。
- BufferedInputStream
继承自FilterInputStream,FilterInputStream继承自InputStream,因此有父类的一些方法方法。
其成员变量有两个值得关注:
//缓冲区
protected volatile byte buf[];
//最大缓冲区大小
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
//默认缓冲区大小
private static int DEFAULT_BUFFER_SIZE = 8192;
//比缓冲区中最后一个有效字节的索引大1的索引。
protected int count;
//缓冲区中下一个被读的字节的位置
protected int pos;
//最后一次调用mark(int readLimit)方法记录的buf中下一个被读取的字节的位置
protected int markpos = -1;
//调用mark后,在后续调用reset方法失败之前允许的从in中读取的最大数据量。用于限制被标记后buffer的最大值。
protected int marklimit;
//为buf提供CAP。关闭可以是异步的。需要CAP保持同步。
//使用buf[]的空值作为该流已关闭的主要指示符。(“in”在关闭时也会被清零。)
private static final
AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
AtomicReferenceFieldUpdater.newUpdater
(BufferedInputStream.class, byte[].class, "buf");
构造方法:
//默认缓冲区,8192个字节
public BufferedInputStream(InputStream in);
//指定缓冲区大小,size字节
public BufferedInputStream(InputStream in, int size);
主要方法:
boolean markSupport(); //流是否支持mark
void mark(int readLimit); //标记当前buf中读取下一个字节的下标
void reset(); //重置最后一次调用mark标记的buf中的位子
long skip(long n); //跳过n个字节。会跳过buf中的有效字节和in的源中的字节
以增强FileInputStream为例
public static void main(String[] args) throws IOException {
//内容是Today is new.
File file = new File("D:\\Willow.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
int len = 0;
while ((len = bufferedInputStream.read()) != -1){
System.out.print((char) len);
if('a'== len){
//记录a的位置
bufferedInputStream.mark(1);
}
}
//复原到刚刚mark的位置
bufferedInputStream.reset();
//读取a后的字符,输出y
System.out.println((char) bufferedInputStream.read());
//输出空格
System.out.println((char) bufferedInputStream.read());
//输出i
System.out.println((char) bufferedInputStream.read());
//输出s
System.out.println((char) bufferedInputStream.read());
}
字符缓冲流
- BufferedWriter
继承自Writer
构造方法:
//默认缓冲区,8192个字节
public BufferedWriter(Writer out);
//指定缓冲区大小,size字节
public BufferedWriter(Writer out, int sz);
方法:
//写入一个行分隔符,会根据不同系统写入正确的行分隔符
void newLine();
以增强FileWriter为例
public static void main(String[] args) throws IOException {
File file = new File("D:\\Willow.txt");
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
for (int i = 0; i < 5;++i){
bufferedWriter.write("你好,明天!");
//替代\r\n
bufferedWriter.newLine();
}
bufferedWriter.flush();
bufferedWriter.close();
}
- BufferedReader
继承自Reader
构造方法:
//默认缓冲区,8192个字节
public BufferedReader(Reader in);
//指定缓冲区大小,size字节
public BufferedReader(Reader in, int sz);
方法:
//读一行数据,需要\n \r \r\n认为某行终止
//读取到该行字符串,不包括终止符,如果读到流末尾,会返回null
String readLine();
以增强FileReader为例
public static void main(String[] args) throws IOException {
File file = new File("D:\\Willow.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null){
System.out.println(line);
}
reader.close();
}
实例
文件拷贝,使用缓冲流效率更高。
public static void main(String[] args) throws IOException {
File file = new File("D:\\others\\一些技术电子书书\\《Java编程思想 (第四版)》.pdf");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\copy.pdf"));
byte[] bytes = new byte[1024];
int len = 0;
long begin = System.currentTimeMillis();
while ((len = in.read(bytes)) != -1){
out.write(bytes,0,len);
}
in.close();
out.close();
long end = System.currentTimeMillis();
System.out.println("用时:" + (end - begin) + "ms");
}