本Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及后续版本中更新的语言特性的摘要。
请参阅JDK发行说明,了解所有JDK版本的新功能、增强功能和已删除或不推荐使用的选项。
Java平台使用Unicode约定存储字符值。字符流I/O会自动将内部格式与本地字符集进行转换。在西方地区,本地字符集通常是ASCII的8位超集。
对于大多数应用程序,使用字符流进行I/O并不比使用字节流更复杂。使用流类进行的输入和输出会自动转换为本地字符集。如果程序使用字符流代替字节流,它会自动适应本地字符集并准备好国际化 ——而无需程序员额外努力。
如果国际化不是首要任务,你可以简单地使用字符流类,不太关注字符集问题。稍后,如果国际化成为首要任务,你的程序可以在不需要大量重写代码的情况下进行调整。请参阅国际化教程以获取更多信息。
所有字符流类都是从Reader和Writer派生而来的。与字节流一样,也有专门用于文件I/O的字符流类:FileReader和FileWriter。示例CopyCharacters演示了这些类的用法。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyCharacters {
public static void main(String[] args) throws IOException {
FileReader inputStream = null;
FileWriter outputStream = null;
try {
inputStream = new FileReader("xanadu.txt");
outputStream = new FileWriter("characteroutput.txt");
int c;
while ((c = inputStream.read()) != -1) {
outputStream.write(c);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
CopyCharacters与CopyBytes非常相似。最重要的区别在于,CopyCharacters使用FileReader和FileWriter来进行输入和输出,而不是使用FileInputStream和FileOutputStream。请注意,CopyBytes和CopyCharacters都使用一个int变量进行读取和写入。然而,在CopyCharacters中,int变量的最后16位保存字符值;在CopyBytes中,int变量的最后8位保存字节值。
字符流通常是字节流的“包装器”。字符流使用字节流执行物理输入/输出,而字符流处理字符和字节之间的转换。例如,FileReader使用FileInputStream,而FileWriter使用FileOutputStream。
有两种通用的字节到字符的“桥接”流:InputStreamReader和OutputStreamWriter。当没有现成的字符流类满足您的需求时,可以使用它们来创建字符流。在网络教程的套接字部分中,展示了如何使用套接字类提供的字节流创建字符流。
字符输入/输出通常以比单个字符更大的单位进行。一个常见的单位是行:一串带有行终止符的字符。行终止符可以是回车/换行序列("\r\n"),单个回车("\r")或单个换行("\n")。支持所有可能的行终止符允许程序读取在任何广泛使用的操作系统上创建的文本文件。
让我们修改CopyCharacters示例以使用面向行的输入/输出。为此,我们需要使用两个我们之前没有见过的类:BufferedReader和PrintWriter。我们将在缓冲输入/输出和格式化中更详细地探讨这些类。现在,我们只对它们支持面向行的输入/输出感兴趣。
CopyLines示例调用BufferedReader.readLine和PrintWriter.println以逐行进行输入和输出。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
public class CopyLines {
public static void main(String[] args) throws IOException {
BufferedReader inputStream = null;
PrintWriter outputStream = null;
try {
inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));
String l;
while ((l = inputStream.readLine()) != null) {
outputStream.println(l);
}
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
}
调用readLine会返回带有行终止符的文本行。CopyLines使用println输出每一行,该方法会自动添加当前操作系统的行终止符。这可能与输入文件中使用的行终止符不同。
除了字符和行之外,还有许多其他的文本输入和输出方式。更多信息请参阅扫描和格式化。