# 字符流

Java 平台使用 Unicode 约定存储字符值。字符流 I / O 自动将此内部格式转换为本地字符集。 在西方语言环境中,本地字符集通常是 ASCII 的 8 位超集。

对于大多数应用,具有字符流的 I / O 并不比具有字节流的 I / O 复杂。 使用流类完成的输入和输出自动转换到本地字符集和从本地字符集转换。 使用字符流代替字节流的程序自动适应本地字符集,并准备好进行国际化 - 所有这些都不需要编程人员的额外努力。

如果国际化不是一个优先事项,您可以简单地使用字符流类,而不需要重视字符集问题。 后来,如果国际化成为优先事项,您的程序可以进行调整,无需广泛的重新编码。有关更多信息,请参阅国际化章节。

# 使用字符流

所有字符流类都来自 ReaderWriter。与字节流一样,有专门用于文件 I / O 的字符流类: FileReaderFileWriter。这个 CopyCharacters 例子说明了这些类。

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();
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

CopyCharactersCopyBytes 非常相似 。 最重要的区别是 CopyCharactersFileReaderFileWriter 输入和输出代替 FileInputStreamFileOutputStream。 注意 CopyBytesCopyCharacters 使用一个 int 变量读取和写入。 然而,在 CopyCharacters int 变量保存其最后 16 位中的字符值; 在 CopyBytes,int 变量 byte 在其最后 8 位中保存一个值。

# 使用字节流的字符流

字符流通常是字节流的“包装器”。字符流使用字节流来执行物理 I / O,而字符流处理字符和字节之间的转换, 例如:FileReader 使用 FileInputStream,FileWriter 使用 FileOutputStream。

有两个通用的字节到字符“桥”流, InputStreamReader 和 OutputStreamWriter。 当没有满足您需求的预包装字符流类时,可以使用它们来创建字符流。 在网络传输中,sockets 展示了如何创建从套接字类提供的字节流的字符流。

# 面向行的 I/O

字符 I / O 通常发生在比单个字符更大的单位中。一个常见的单位是行:一个字符串,在末尾有一个行终止符。 线路终端器可以是回车/换行顺序("\r\n"),单个回车("\r")或单行换行("\n")。 支持所有可能的线路终端器允许程序读取在任何广泛使用的操作系统上创建的文本文件。

我们来修改 CopyCharacters 示例来使用面向行的 I / O。要做到这一点,我们必须用我们以前没有见过两个类, BufferedReader 和 PrintWriter。我们将在缓冲 I / O 和格式化中更深入地探索这些类。 现在,我们只是对他们对面向行的 I / O 的简单介绍

CopyLines 示例调用 BufferedReader.readLine 和 PrintWriter.println 一次输入和输出一行。

 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();
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

调用 readLine 返回一行文本。CopyLines 输出每行使用 println,其附加用于当前操作系统的行终止符。 这可能与输入文件中使用的行终止符不同。

有很多方法来实现文字输入输出一行的功能。有关信息,请参阅 扫描和格式化。