Character Streams

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

对于大多数应用程序,使用字符流的 I/O 并不比使用字节流的 I/O 复杂。使用流类完成的 Importing 和输出会自动与本地字符集进行转换。使用字符流代替字节流的程序会自动适应本地字符集,并可以进行国际化,而这一切都无需程序员付出额外的精力。

如果国际化不是优先事项,则可以简单地使用字符流类,而不必过多关注字符集问题。以后,如果国际化成为当务之急,则无需大量重新编码即可修改您的程序。有关更多信息,请参见Internationalization

使用字符流

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

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();
            }
        }
    }
}

CopyCharactersCopyBytes非常相似。最重要的区别是CopyCharacters使用FileReaderFileWriter代替FileInputStreamFileOutputStream进行 Importing 和输出。请注意,CopyBytesCopyCharacters都使用int变量进行读取和写入。但是,在CopyCharacters中,int变量在最后 16 位保留一个字符值;在CopyBytes中,int变量的最后 8 位保留byte值。

使用字节流的字符流

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

有两个通用的字节到字符“bridge”流:InputStreamReaderOutputStreamWriter。当没有预打包的字符流类可以满足您的需求时,使用它们来创建字符流。 networking trail中的sockets lesson显示了如何从套接字类提供的字节流中创建字符流。

Line-Oriented I/O

字符 I/O 通常以比单个字符大的单位出现。行是一个常见的单位:一 String 字符,末尾有一个行终止符。换行符可以是回车/换行序列("\r\n"),单个回车("\r")或单个换行("\n")。支持所有可能的行终止符,使程序可以读取在任何广泛使用的 os 上创建的文本文件。

让我们修改CopyCharacters示例以使用面向行的 I/O。为此,我们必须使用从未见过的两个类BufferedReaderPrintWriter。我们将在Buffered I/OFormatting中更深入地探讨这些类。现在,我们只是对他们对基于行的 I/O 的支持感兴趣。

CopyLines示例调用BufferedReader.readLinePrintWriter.println一次 Importing 和输出一行。

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输出每行,该行将为当前 os 附加行终止符。这可能与 Importing 文件中使用的行终止符不同。

除了字符和行以外,还有许多种方法来构造文本 Importing 和输出。有关更多信息,请参见扫描和格式化