将字符串写入输出流

161

我有几个实现了OutputStream的输出监听器。 它们可以将内容写入stdout或文件,也可以写入内存或任何其他输出目标。因此,在该方法中,我将OutputStream指定为参数。

现在,我已经收到了String。那么,在这里写入流的最佳方式是什么呢?

我应该只使用Writer.write(message.getBytes())吗?我可以传入字节,但如果目标流是字符流,它会自动转换吗?

我需要在这里使用一些桥接流吗?


2
我不确定,但这听起来像是你在尝试重新发明轮子,你是否查看了Java Base API以及Commons IO API? - posdef
6个回答

164

InputStreamOutputStream用于传输二进制数据。如果你想将一个字符串写入到流中,你必须先将其转换为字节,也就是说要进行编码。你可以手动完成这个过程(如你所建议)使用String.getBytes(Charset)方法,但应该避免使用String.getBytes()方法,因为它使用JVM的默认编码,这在可移植性方面无法可靠地预测。

通常将字符数据写入流的方式是将流包装在一个Writer(通常是PrintWriter)中,在调用其write(String)(或print(String))方法时进行转换。对于InputStreams相应的包装器是Reader

PrintStream是一种特殊的OutputStream实现,因为它还包含自动编码字符串的方法(它在内部使用一个writer)。但它仍然是一种流。无论你的流是PrintStream还是其他的流实现,你都可以安全地将其包装在一个writer中。没有二重编码的危险。

PrintWriter与OutputStream的示例:

try (PrintWriter p = new PrintWriter(new FileOutputStream("output-text.txt", true))) {
    p.println("Hello");
} catch (FileNotFoundException e1) {
    e1.printStackTrace();
}

7
使用PrintWriter就像使用String.getBytes()一样,它使用JVM默认的随机编码。所以只有当你运气好时才能正常工作。 - Christoffer Hammarström
1
代码片段应该真的使用一个同时接受Charset参数的构造函数,尤其是考虑到答案的第一段... - undefined
代码片段应该真正使用一个构造函数,该构造函数还接受一个 Charset 参数,特别是考虑到答案的第一段。 - morgwai

124

OutputStream写入字节,而String提供字符。您需要定义字符集(Charset)来将字符串编码为byte[]:

outputStream.write(string.getBytes(Charset.forName("UTF-8")));

UTF-8 改为您选择的字符集。


3
请追加以下代码行:ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - Sahil Patel
6
.getBytes(StandardCharsets.UTF_8) 稍微更清晰一些。 - bb1950328

35
您可以创建一个围绕着您的 OutputStream 的 PrintStream,然后只需调用它的 print(String) 方法即可:
final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();

4
PrintStream使用哪种字符集将文本转换为字节? - Dean Hiller

30

按照设计,应该以这种方式完成:

OutputStream out = ...;
try (Writer w = new OutputStreamWriter(out, "UTF-8")) {
    w.write("Hello, World!");
} // or w.close(); //close will auto-flush

5
请注意,w.close()将同时关闭out - Franklin Yu
1
我更喜欢这个答案,因为它提供了明确的编码规范!我建议使用现有的预定义编码,例如StandardCharsets.UTF_8,而不是字符串字面量("UTF-8")。 - HooNose

13

使用PrintWriter包装您的OutputStream,并使用该类上的打印方法。它们接收一个字符串并为您完成工作。


9

IOUtils.write(String data, OutputStream output, Charset encoding) 的实现方式是 output.write(data.getBytes(Charsets.toCharset(encoding))),因此如果一个编码后的字符串无法适应一个字节数组,则可能会出现问题。 - Šarūnas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接