# 字符和字节流

> 原文： [https://docs.oracle.com/javase/tutorial/i18n/text/stream.html](https://docs.oracle.com/javase/tutorial/i18n/text/stream.html)

`java.io`包提供的类允许您在 Unicode 字符流和非 Unicode 文本的字节流之间进行转换。使用 [`InputStreamReader`](https://docs.oracle.com/javase/8/docs/api/java/io/InputStreamReader.html) 类，可以将字节流转换为字符流。您使用 [`OutputStreamWriter`](https://docs.oracle.com/javase/8/docs/api/java/io/OutputStreamWriter.html) 类将字符流转换为字节流。下图说明了转换过程：

<center>![This figure represents the conversion process](img/33c102f8a405f1856fcfa8f989e079bd.jpg)</center>

创建`InputStreamReader`和`OutputStreamWriter`对象时，指定要转换的字节编码。例如，要将 UTF-8 编码的文本文件转换为 Unicode，请按如下方式创建`InputStreamReader`：

```
FileInputStream fis = new FileInputStream("test.txt");
InputStreamReader isr = new InputStreamReader(fis, "UTF8");

```

如果省略编码标识符，`InputStreamReader`和`OutputStreamWriter`依赖于默认编码。您可以通过调用`getEncoding`方法确定`InputStreamReader`或`OutputStreamWriter`使用的编码，如下所示：

```
InputStreamReader defaultReader = new InputStreamReader(fis);
String defaultEncoding = defaultReader.getEncoding();

```

下面的示例显示如何使用`InputStreamReader`和`OutputStreamWriter`类执行字符集转换。此示例的完整源代码位于 [`StreamConverter.java`](examples/StreamConverter.java) 中。该程序显示日文字符。在尝试之前，请验证系统上是否安装了相应的字体。如果您使用的是与 1.1 版兼容的 JDK 软件，请复制`font.properties`文件，然后将其替换为`font.properties.ja`文件。

`StreamConverter`程序将`String`对象的 Unicode 字符序列转换为以 UTF-8 编码的字节的`FileOutputStream`。执行转换的方法称为`writeOutput`：

```
static void writeOutput(String str) {
    try {
        FileOutputStream fos = new FileOutputStream("test.txt");
        Writer out = new OutputStreamWriter(fos, "UTF8");
        out.write(str);
        out.close();
    } 
    catch (IOException e) {
        e.printStackTrace();
    }
}

```

`readInput`方法从`writeOutput`方法创建的文件中读取以 UTF-8 编码的字节。 `InputStreamReader`对象将 UTF-8 中的字节转换为 Unicode，并在`String`中返回结果。 `readInput`方法如下：

```
static String readInput() {
    StringBuffer buffer = new StringBuffer();
    try {
        FileInputStream fis = new FileInputStream("test.txt");
        InputStreamReader isr = new InputStreamReader(fis, "UTF8");
        Reader in = new BufferedReader(isr);
        int ch;
        while ((ch = in.read()) > -1) {
            buffer.append((char)ch);
        }
        in.close();
        return buffer.toString();
    } 
    catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

```

`StreamConverter`程序的`main`方法调用`writeOutput`方法创建以 UTF-8 编码的字节文件。 `readInput`方法读取相同的文件，将字节转换回 Unicode。这是`main`方法的源代码：

```
public static void main(String[] args) {
    String jaString = new String("\u65e5\u672c\u8a9e\u6587\u5b57\u5217");
    writeOutput(jaString); 
    String inputString = readInput();
    String displayString = jaString + " " + inputString;
    new ShowString(displayString, "Conversion Demo");
}

```

原始字符串（`jaString`）应与新创建的字符串（`inputString`）相同。为了显示两个字符串是相同的，程序将它们连接起来并用`ShowString`对象显示它们。 `ShowString`类使用`Graphics.drawString`方法显示字符串。该类的源代码位于 [`ShowString.java`](examples/ShowString.java) 中。当`StreamConverter`程序实例化`ShowString`时，出现以下窗口。显示的字符重复验证两个字符串是否相同：

<center>![This is a screens hot of the StreamConverter program](img/6bed01d5c44a9c8dc3fce2bda11a9cc0.jpg)</center>