1、转换流OutputStreamWriter与InputStreamReader
Java中的字符是Unicode编码,是双字节的,InputStream与OutputStream是用来处理字节的,在处理字符文本时需要额外的程序代码。Java为字符文本的输入输出专门提供一套单独的类,Reader、Writer两个抽象类与InputStream、OutputStream两个类相同。可以在处理字符串时简化了我们的编程。
OutputStreamWriter与InputStreamReader这两个类把字节流转换成字符流,中间做了数据的转换,类似适配器模式的思想。
1.1 OutputStreamWriter
OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
构造方法:
OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流。
OutputStreamWriter(OutputStream out,String charsetName):
根据指定编码把字节流数据转换为字符流。把字节流转换为字符流,字符流 = 字节流 + 编码表。
使用示例:向文本文件写入字符文本
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//IO.txt文件的格式为UTF-8
OutputStreamWriter osw = new OutputStreamWriter(new
FileOutputStream("IO.txt"), "UTF-8");
osw.write("中国");
osw.close();
}
}
OutputStreamWriter的方法:
public void write(int c):写一个字符
public void write(char[] cbuf):写一个字符数组
public void write(char[] cbuf,int off,int len):写一个字符数组的一部分
public void write(String str):写一个字符串
public void write(String str,int off,int len):写一个字符串的一部分
close()和flush()的区别?
A:close()在关闭流对象之前,先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("IO.txt"));
osw.write("我爱北京天安们", 2, 3);
osw.flush();
osw.close();
}
}
1.2 InputStreamReader
InputStreamReader:是字节流通向字符流的桥梁,它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
构造方法:
InputStreamReader(InputStream is):用默认的编码读取数据
InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据
使用示例:从文本文件读取字符文本
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//IO.txt文件的格式为UTF-8
InputStreamReader isr = new InputStreamReader(new
FileInputStream("IO.txt"), "UTF-8");
//一次读取一个字符
int ch = 0;
while ((ch = isr.read()) != -1) {
System.out.print((char) ch);
}
isr.close();
}
}
InputStreamReader的方法
int read():一次读取一个字符
int read(char[] chs):一次读取一个字符数组
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("IO.txt"));
// 一次读取一个字符数组
char[] chs = new char[1024];
int len = 0;
while ((len = isr.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
isr.close();
}
}
1.3 通过字符流进行文件复制
需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new
FileOutputStream("b.txt"));
char[] chs = new char[1024];
int len = 0;
while ((len = isr.read(chs)) != -1) {
osw.write(chs, 0, len);
}
osw.close();
isr.close();
}
}
2 FileReader与FileWriter
2.1 FileReader与FileWriter源码分析
继承InputStreamReader与OutputStreamWriter类
【FileReader源码】
public class FileReader extends InputStreamReader {
public FileReader(String fileName) throws FileNotFoundException {
super(new FileInputStream(fileName));
}
public FileReader(File file) throws FileNotFoundException {
super(new FileInputStream(file));
}
public FileReader(FileDescriptor fd) {
super(new FileInputStream(fd));
}
}
【FileWriter源码】
public class FileWriter extends OutputStreamWriter {
public FileWriter(String fileName) throws IOException {
super(new FileOutputStream(fileName));
}
public FileWriter(String fileName, boolean append) throws IOException {
super(new FileOutputStream(fileName, append));
}
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
}
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
}
public FileWriter(FileDescriptor fd) {
super(new FileOutputStream(fd));
}
}
2.2 使用FileReader与FileWriter进行文本复制
由于我们常见的操作都是使用本地默认编码,所以,不用指定编码。而转换流的名称有点长,所以,Java就提供了其子类供我们使用。
OutputStreamWriter = FileOutputStream + 编码表(GBK)
FileWriter = FileOutputStream + 编码表(GBK)
InputStreamReader = FileInputStream + 编码表(GBK)
FileReader = FileInputStream + 编码表(GBK)
public class CopyFileDemo2 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {
fw.write(chs, 0, len);
fw.flush();
}
fw.close();
fr.close();
}
}
3、字符缓冲流BufferedReader与BufferedWriter
字符流为了高效读写,也提供了对应的字符缓冲流
BufferedWriter:字符缓冲输出流
BufferedReader:字符缓冲输入流
3.1 BufferedWriter
构造函数:
BufferedWriter(Writer out)
BufferedWriter(Writer out, int sz)
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。 可以指定缓冲区的大小,或者接受默认的大小。
使用案例:
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("IO.txt"));
bw.write("hello");
bw.write("world");
bw.flush();
bw.close();
}
}
3.2 BufferedReader
构造函数:
BufferedReader(Reader in)
BufferedReader(Reader in, int sz)
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 可以指定缓冲区的大小,或者可使用默认的大小。
使用案例:
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("IO.txt"));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}
br.close();
}
}
3.3字符缓冲流特有的方法newLine( )和readLine( )
字符缓冲流的特殊方法:
BufferedWriter:public void newLine():
根据系统来决定换行符,行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 (‘\n’) 符。
BufferedReader:public String readLine():
使用案例:
public class BufferedDemo {
public static void main(String[] args) throws IOException {
write();
read();
}
private static void read() throws IOException {
BufferedReader br = new BufferedReader(new FileReader("IO.txt"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
private static void write() throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("IO.txt"));
for (int x = 0; x < 3; x++) {
bw.write("hello" + x);
// bw.write("\r\n");
bw.newLine();
bw.flush();
}
bw.close();
}
}
/*IO.txt的文本内容
hello0
hello1
hello2
*/
4 文本复制的方法
文本复制方法一:逐个字符读取
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
bw.flush();
}
bw.close();
br.close();
}
}
文本复制方法二:逐行文本读取
public class CopyFileDemo2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}