Java的IO操作(五) - PrintStream类、字符流、Reader和Writer、带缓冲的字符流BufferedReader和BufferedWriter
1. PrintStream类
我们都知道,int类型在Java中占4个字节,如1在内存中表示为 00000000 00000000 00000000 00000001。如果我们直接使用OutputStream对象输出到一个文件中的话,那么程序就会向文件中直接写入 00000001。不用说,用记事本打开的话肯定会是一个奇怪的字符。现在我们想要将内存中的数据转换成字符型再输出到文件中,就可以使用PrintStream类。
PrintStream类会自动将数据转换为字符,这样在我们用文本编辑器打开的时候,整型变量1就会看到一个1,而不是乱码了。如:
package cls; import java.io.*; public class PrintStreamDemo { public static void main(String[] args) throws Exception { // 使用OutputStream对象输出 FileOutputStream fos = new FileOutputStream("OutputStream.txt"); fos.write(1); // 写入整型数据1 fos.close(); // 使用PrintStream对象输出 PrintStream ps = new PrintStream(new FileOutputStream("PrintStream.txt")); ps.println(2); // 写入整型 ps.println(3.14); // 写入double型 ps.println(new String("Hello World!")); // 写入String类型 ps.close(); } }
2. 字符流Reader和Writer
java.io.Reader、java.io.Writer和其子类是处理字符流的相关类。也就是说,这些类对出数据会以一个字符(2个字节)的长度为单位进行处理,适合对纯文本文件的读写。
和java.io.InputStream、java.io.OutputStream类似,Reader和Writer是一个抽象类,我们一般会用其子类来实现相关的操作。
下面的代码说明了InputStreamReader和OutputStreamWriter的使用方法:
package cls; import java.io.*; public class IODemo { public static void main(String[] args) throws Exception { FileInputStream fis = new FileInputStream("input.txt"); // 为文件输入流加上字符处理功能 InputStreamReader isr = new InputStreamReader(fis); // 从文件中读取字符 int ch = 0; while((ch = isr.read()) != -1) { System.out.print((char)ch); } System.out.println(); // 关闭流 isr.close(); } }
FileReader和FileWriter这2个子类能够方便地读写纯文本文件。如以下示例,我们把Linux下的文本文件的换行符转换成Windows格式的换行符:
package cls; import java.io.*; class FileReaderDemo { public static void main(String[] args) throws Exception { FileReader fileReader = new FileReader("input.txt"); FileWriter fileWriter = new FileWriter("output.txt"); int ch = 0; char[] wrapChar = new char[]{'\r','\n'}; while((ch = fileReader.read()) != -1) { if(ch == '\n') // 如果是换行符 { // 写入 \r\n 换行符 fileWriter.write(wrapChar); } else { fileWriter.write(ch); } } // 关闭流 fileReader.close(); fileWriter.close(); } }
BufferedReader和BufferedWriter各有8192字符的缓冲区。当BufferedReader在读取文本文件时,会尽量去填满缓冲区,之后如果调用了read()方法,则该类会从缓冲区中读取数据。同理,BufferedWriter会先向缓冲区中写入数据,缓冲区满后才将数据写入到文件中。
示例程序:
package cls; import java.io.*; class BufferedReaderDemo { public static void main(String[] args) throws IOException { // 字符输入流 InputStreamReader inputReader = new InputStreamReader(System.in); BufferedReader bufReader = new BufferedReader(inputReader); // 为输入加上缓冲功能 // 文件字符输出流 FileWriter fileWriter = new FileWriter("output.txt"); BufferedWriter bufWriter = new BufferedWriter(fileWriter); // 为输出流加上缓冲功能 String input = null; // 每次从标准输入中读入一行字符,直到quit结束 while(!(input = bufReader.readLine()).equals("quit")) { bufWriter.write(input); bufWriter.newLine(); // 输出与OS相关的换行符 } // 关闭流 bufReader.close(); bufWriter.close(); } }