Java IO:OutputStreamWriter 类

在 Java 的 I/O 体系里,java.io.OutputStreamWriter 类用于封装 OutputStream类  ,把基于字节的输出流转变为基于字符的 Writer。而且,它能封装 OutputStream 的任意子类。

若要向如 UTF-8 或 UTF-16 编码的文件写入字符,OutputStreamWriter 类将会很实用。你可以向OutputStreamWriter 写入字符(字符值),它会对这些字符进行正确编码,再将编码后的字节写入底层的 OutputStream。

Java 的 OutputStreamWriter 是 Writer 类的子类。所以,在任何需要 Writer 的地方都能使用它。

OutputStreamWriter 示例

下面是一个简单的 Java OutputStreamWriter 示例:

package com.hxstrive.java_io;

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class OutputStreamWriterExample {
    public static void main(String[] args) throws Exception {
        // 写出数据
        try(OutputStreamWriter outputStreamWriter =
                    new OutputStreamWriter(new FileOutputStream("output.txt"))){
            outputStreamWriter.write("Hello World");
        }
    }
}

字符编码构造函数

OutputStreamWriter 类还有其他构造函数,允许您指定字符集(如 ISO-Latin1、GBK、UTF-8、UTF-16 等),以便将写入的字符转换为写入底层 OutputStream 的字节。例如:

try(OutputStreamWriter outputStreamWriter =
            new OutputStreamWriter(new FileOutputStream("output.txt"), StandardCharsets.UTF_8)){
    outputStreamWriter.write("Hello World");
}

上述示例,创建了一个 OutputStreamWriter,它将把写入的所有字符转换为 UTF-8 编码字符(每个字符由一个或多个字节组成),并将 UTF-8 编码字节写入底层的 OutputStream。

write(int)

OutputStreamWriter 类的 write(int) 方法,将 int 的低 16 位作为一个字符写入 OutputStreamWriter 所连接的目标。例如:

OutputStreamWriter outputStreamWriter = 
    new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8");
outputStreamWriter.write('A');

write(char[])

OutputStreamWriter 类还有一个 write(char[]) 方法,可将字符数组写入 OutputStreamWriter 所连接的目标。write(char[]) 方法返回实际写入 OutputStreamWriter 的字符数。例如:

OutputStreamWriter outputStreamWriter = 
    new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8");

char[] chars = new char[]{'A','B','C','D','E'};
outputStreamWriter.write(chars);

注意,向 OutputStreamWriter 写入字符数组比一次写入一个字符要快。速度的提升可能非常明显,甚至可高达 10 倍或更多。因此,建议尽可能使用 write(char[]) 方法。

具体的速度提升取决于运行 Java 代码的计算机的底层操作系统和硬件、内存速度、硬盘速度和缓冲区大小、网卡速度和缓冲区大小等问题,以及 OutputStreamWriter 将数据发送到哪个目的地(本地磁盘比网络连接更快)。

通过 BufferedWriter 实现透明缓冲

通过将 OutputStreamWriter 包装成 BufferedWriter,可以对写入 OutputStreamWriter 的字符进行透明缓冲。写入 BufferedWriter 的所有字节都将首先被缓冲到 BufferedWriter 的内部字符数组中。缓冲区满后,缓冲区会被一次性刷新到底层的 OutputStreamWriter 中。

public class BufferedWriter extends Writer {
    private Writer out;
    private char cb[];
    private int nChars, nextChar;
    //...
}

下面将创建一个 BufferedWriter:

Writer writer = new BufferedWriter(
        new OutputStreamWriter(
            new FileOutputStream("c:\\data\\output-file.txt"), "UTF-8"), 8192);

通过 BufferedOutputStream 实现透明缓冲

另一种为写入 OutputStreamWriter 的字符添加透明缓冲的方法是,先将 OutputStream 封装为 BufferedOutputStream,然后再将其封装为 OutputStreamWriter。

写入 BufferedOutputStream 的所有字节都将首先在 BufferedOutputStream 的内部字节数组中得到缓冲。当缓冲区满时,缓冲区会被一次性刷新到底层的 OutputStream 中。例如:

OutputStreamWriter outputStreamWriter =
    new OutputStreamWriter(
        new BufferedOutputStream(
              new FileOutputStream("c:\\data\\output-file.txt"), 8192), "UTF-8");

flush()

OutputStreamWriter 的 flush() 方法会将写入 OutputStreamWriter 的所有数据刷新到底层数据目标。例如,如果 OutputStreamWriter 是 FileWriter,那么写入 FileWriter 的字节可能尚未完全写入磁盘。即使您的 Java 代码已将数据写入 FileWriter,数据也可能在操作系统内存的某个地方缓冲。

通过调用 flush(),你可以确保任何缓冲数据都将被刷新(写入)到磁盘(或网络,或 OutputStreamWriter 的其他目标)。例如:

outputStreamWriter.flush();

关闭 OutputStreamWriter

当完成向 OutputStreamWriter 写入字符后,记得关闭它。关闭 OutputStreamWriter 也会关闭 OutputStreamWriter 正在写入的 OutputStream 实例。

关闭 OutputStreamWriter 仅需要调用它的 close() 方法,如下:

outputStreamWriter.close();

甚至,你还可以使用 Java7 中引入的 try-with-resources 结构。例如:

OutputStream output = new FileOutputStream("data/data.bin");
try(OutputStreamWriter outputStreamWriter =
    new OutputStreamWriter(output)){

    Person person = new Person();
    person.name = "Tom";
    person.age = 34;

    outputStreamWriter.writeObject(person);
}

注意,上述示例没有任何明确调用 close() 方法,调用 close() 方法由 try-with-resources 负责。

还需注意,第一个 FileOutputStream 实例并没有在 try-with-resources 代码块中创建。这意味着 try-with-resources 代码块不会自动关闭 FileOutputStream 实例。不过,当 OutputStreamWriter 关闭时,它也会关闭它所写入的 OutputStream 实例,因此 FileOutputStream 实例会在 OutputStreamWriter 关闭时被关闭。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号