赞
踩
缓冲流是处理流的一种,也叫高效流,是对4个基本输入输出流的增强,它让输入输出流具有1个缓冲区,能显著减小与外部的IO次数,从而提高读写的效率,并且提供了一些额外的读写方法。
因为是对4个基本输入输出流的增强,因此缓冲流也有4个,分为字节缓冲流和字符缓冲流。
构造方法:
BufferedOutputStream(OutputStream out)
:创建一个新的缓冲输出流,以将数据写入指定的底层输出流。BufferedInputStream(InputStream in)
:创建一个 BufferedInputStream
并保存其参数,即输入流 in
,以便将来使用。常用方法:
字节缓冲流常用方法基本与字节流的方法一样。
示例:通过复制大文件测试缓冲流的效率
使用基本流:
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class TestBuffered { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("File\\new.tar.gz"); FileInputStream fis = new FileInputStream("test.tar.gz"); int len; byte[] bytes = new byte[1024]; long start = System.currentTimeMillis(); while((len = fis.read(bytes)) != -1) { fos.write(bytes, 0, len); } System.out.println("使用时间:" + (System.currentTimeMillis() - start) + "毫秒"); fos.close(); fis.close(); } }
耗时:36719毫秒
使用缓冲流:
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; public class TestBuffered { public static void main(String[] args) throws IOException { // FileOutputStream fos = new FileOutputStream("File\\new.tar.gz"); // FileInputStream fis = new FileInputStream("test.tar.gz"); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("File\\new.tar.gz")); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.tar.gz")); int len; byte[] bytes = new byte[1024]; long start = System.currentTimeMillis(); while((len = bis.read(bytes)) != -1) { bos.write(bytes, 0, len); } System.out.println("使用时间:" + (System.currentTimeMillis() - start) + "毫秒"); bos.close(); bis.close(); } }
耗时:26595毫秒
构造方法:
BufferedWriter(Writer out)
:创建一个使用默认大小输出缓冲区的缓冲字符输出流。BufferedReader(Reader in)
:创建一个使用默认大小输入缓冲区的缓冲字符输入流。常用方法:
字符缓冲流的基本方法与普通字符流基本一致。
特有方法:
字符缓冲流新有的方法:
void newLine()
写入一个行分隔符。根据系统属性定义换行符String readLine()
读取一个文本行。每次读取一行示例:void newLine()
import java.io.*; import java.io.IOException; public class TestBuffered { public static void main(String[] args) throws IOException { BufferedWriter bw = new BufferedWriter(new FileWriter("File\\b.txt")); bw.write("你好"); bw.newLine(); // 换行 bw.write("我是中国人"); bw.newLine(); // 换行 bw.close(); } }
示例:String readLine()
import java.io.*;
import java.io.IOException;
public class TestBuffered {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("File\\a.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
}
注意:
readLine()读取到末尾后再读取,返回的是null,不再是-1了。
讲到转换流之前,涉及到一个编码与解码的问题,一般来说,使用规则A编码,则需要使用A规则解码才可以正常显示文本符号,而在Java中不同的编码方式,中文所占的字节数不同,所以当使用不同编码时,需要对应的编码方式的解码才能正常显示中文,否则将会导致乱码的现象。比如使用GBK编码,却用UTF-8解码,将会变成乱码。
讲到编码就会提到一个叫字符集的东西,字符集也叫编码表,是一个系统支持的所有字符的集合。常见的字符集有:ASCII,GBK,Unicode等。
编码相关介绍可参考:
总之涉及到中文,今后编码格式统一都为:UTF-8
为了解决存在的乱码问题,我们需要将字节流转成字符流 或字符流转成字节流,并指定编码格式。
Java提供了两个转换流:OutputStreamWriter和InputStreamReader
OutputStreamWriter是Writer的子类,是字符流通向字节流的桥梁,可以使用指定的charset将要写入流的字符编码成字节。它的字符集可以显示指定,否则将使用平台默认的字符集。
构造方法:
OutputStreamWriter(OutputStream out)
:创建使用默认字符编码的 OutputStreamWriter。OutputStreamWriter(OutputStream out, String charsetName)
:创建使用指定字符集的 OutputStreamWriter。示例:指定编码写文件
import java.io.*;
public class TestOutputStreamWriter {
public static void main(String[] args) throws IOException{
// 指定UTF-8的编码格式,写入
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("File\\d.txt"),"utf-8");
osw.write("中国");
osw.close();
}
}
打开文件d.txt,如下图:
import java.io.*;
public class TestOutputStreamWriter {
public static void main(String[] args) throws IOException{
// 指定GBK的编码格式,写入
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("File\\d.txt"),"GBK");
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("File\\d.txt"));
osw.write("中国");
osw.close();
}
}
打开文件d.txt,如下图
说明:
程序是在Windows下编译运行的,Windows默认编码集为GBK,所以当代码指定UTF-8编码写入文件时候,Windows下打开的是乱码;而当指定GBK编码,或者使用系统默认编码时候,Windows打开时候是正常显示的。
所以,在开发中,以何种编码写入,就必须要以同种编码读取,否则会产生乱码。
InputStreamReader是Reader的子类,是字节流通向字符流的桥梁,可以使用指定的charset读取字节并将其解码为字符。它的字符集可以显示指定,否则将使用平台默认的字符集。
构造方法:
InputStreamReader(InputStream in)
:创建一个使用默认字符集的 InputStreamReader。InputStreamReader(InputStream in ,String charsetName)
:创建使用指定字符集的 InputStreamReader。示例:指定编码读取文件
import java.io.*; public class TestInputStreamReader { public static void main(String[] args) throws IOException { // 文件c.txt内容为:你好,编码为:UTF-8 InputStreamReader isr = new InputStreamReader(new FileInputStream("File\\c.txt"),"UTF-8"); int r; while((r = isr.read()) != -1) { System.out.print((char)r); } isr.close(); System.out.println("=================="); InputStreamReader isr1 = new InputStreamReader(new FileInputStream("File\\c.txt"),"GBK"); int r1; while((r1 = isr1.read()) != -1) { System.out.print((char)r1); // 浣犲ソ } isr1.close(); } }
同理,当保存的文件的编码时UTF-8时候,只有使用UTF-8的编码去读取文件才能得到正常的显示。
说明:
磁盘文件是以字节的方式存储的,内存中的程序时以字符存储的。
所以当写文件到磁盘中时,需要先将程序中的数据(字符)使用OutputStreamWriter转换为字节,在写入文件(因此OutputStreamWriter就是字符到字节的桥梁)
当从磁盘中读取文件时,文件是以字节的方式存储的,所以需要先将字节使用InputStreamReader转换为字符,再读取到内存的程序中。(因此InputStreamReader就是字节到字符的桥梁)
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。