简体   繁体   English

字符流通常是字节流的“包装器”

[英]Character streams often “wrappers” for byte streams

While going through character stream information in java IO Stream, I found following lines hard to understand:在查看 java IO Stream 中的字符流信息时,我发现以下几行难以理解:

Character streams often “wrappers” for byte streams.字符流通常是字节流的“包装器”。 the character stream uses the byte stream to perform the physical I/O, while the character stream handles translation between characters and bytes.字符流使用字节流来执行物理 I/O,而字符流则处理字符和字节之间的转换。 FileReader, for example, uses FileInputStream, while FileWriter uses FileOutputStream.例如,FileReader 使用 FileInputStream,而 FileWriter 使用 FileOutputStream。

would someone help me to understand... Thank you有人能帮我理解...谢谢

At the lowest level a file consists of a byte sequence.在最低级别,文件由字节序列组成。 The meaning of these bytes depends on the application which is responsible to read and write these bytes.这些字节的含义取决于负责读写这些字节的应用程序。 The bytes can be interpreted as a JPEG image, a MP3 sound file or a text.这些字节可以解释为 JPEG 图像、MP3 声音文件或文本。

For a text interpretation you need a mapping between bytes and characters.对于文本解释,您需要字节和字符之间的映射。 These mappings are called character encodings.这些映射称为字符编码。 There are many different character encodings out there.有许多不同的字符编码。 For simple character encodings like Windows ANSI (Cp1252) or DOS encoding (Cp437) there is a one to one relationship between bytes and characters.对于像 Windows ANSI (Cp1252) 或 DOS 编码 (Cp437) 这样的简单字符编码,字节和字符之间存在一对一的关系。 So every character is encoded as exactly one byte.所以每个字符都被编码为一个字节。

But there are more complex encodings like UTF-8.但是还有更复杂的编码,比如 UTF-8。 The byte sequence for one character may consist of one byte or two or more bytes.一个字符的字节序列可以由一个字节或两个或更多字节组成。

In Java the byte level is handled by the byte stream classes like FileInputStream and FileOutputStream .在 Java 中,字节级别由字节流类(如FileInputStreamFileOutputStream For character streams (text) there are the subclasses of Reader and Writer .对于字符流(文本),有ReaderWriter的子类。

The two classes InputStreamReader and OutputStreamWriter are very important here, because these form the connection between character and byte streams. InputStreamReaderOutputStreamWriter两个类在这里非常重要,因为它们形成了字符流和字节流之间的连接。

An InputStreamReader is a Reader so you can read characters out of it. InputStreamReader是一个Reader因此您可以从中读取字符。 But it wraps an InputStream a byte stream.但它将InputStream包装为字节流。 Internally it reads the bytes of the wrapped bytes stream and translate these bytes to characters according to a character encoding.在内部,它读取包装字节流的字节,并根据字符编码将这些字节转换为字符。

An OutputStreamWriter is a Writer .一个OutputStreamWriter是一个Writer You write characters or strings into it.您将字符或字符串写入其中。 The OutputStreamWriter wraps an OutputStream . OutputStreamWriter包装一个OutputStream The characters are mapped to bytes with the encoding are written to the OutputStream .字符被映射到字节,编码被写入OutputStream

If the character encoding isn't specified in the constructor then the platform's default encoding is used (usually Windows-ANSI on Windows and UTF-8 on Linux).如果在构造函数中未指定字符编码,则使用平台的默认编码(通常在 Windows 上使用 Windows-ANSI,在 Linux 上使用 UTF-8)。

Example: To write the String Pelé to the file name.txt in UTF-8:示例:以 UTF-8 格式将字符串Pelé写入文件name.txt

try(Writer writer = new OutputStreamWriter(new FileOutputStream("names.txt"), StandardCharsets.UTF_8)) {
  writer.write("Pelé");
} catch (IOException e) {
  e.printStackTrace();
}

Usually, you add additional Writers, eg for buffering or printing:通常,您添加额外的 Writers,例如用于缓冲或打印:

try(PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
    new FileOutputStream("names.txt"), StandardCharsets.UTF_8)))) {
  writer.println("Pelé");
} catch (IOException e) {
  e.printStackTrace();
}

To be complete, here is the corresponding reading example.为了完整起见,这里是相应的阅读示例。 Here we use Files.newBufferedReader() to create a FileInputStream wrapped by a BufferedReader :这里我们使用Files.newBufferedReader()创建一个由BufferedReader包装的FileInputStream

Path namesFile = Paths.get("names.txt");
try(BufferedReader reader = Files.newBufferedReader(namesFile, StandardCharsets.UTF_8)) {
  reader.lines().forEach(System.out::println);
} catch (IOException e) {
  e.printStackTrace();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM