【问题标题】:Write string to output stream将字符串写入输出流
【发布时间】:2011-05-03 09:54:11
【问题描述】:

我有几个正在实现OutputStream 的输出侦听器。 它可以是 PrintStream 写入标准输出或文件,也可以是写入内存或任何其他输出目标;因此,我将OutputStream 指定为方法中的(一个)参数。

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

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

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

【问题讨论】:

  • 我不确定,但这听起来像是您想在这里重新发明轮子,您是否查看过 Java Base API 以及 Commons IO API?

标签: java io stream outputstream


【解决方案1】:

流(InputStreamOutputStream)传输二进制数据。如果要将字符串写入流,则必须首先将其转换为字节,或者换句话说编码。您可以使用 String.getBytes(Charset) 方法手动(如您所建议的那样)执行此操作,但您应该避免使用 String.getBytes() 方法,因为它使用 JVM 的默认编码,无法以可移植的方式可靠地预测。

不过,将字符数据写入流的常用方法是将流包装在 Writer(通常是 PrintWriter)中,当您调用其 write(String)(或print(String)) 方法。 InputStreams 对应的包装是Reader

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

带有 OutputStream 的 PrintWriter 示例:

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

【讨论】:

  • 所以使用PrintWriter就像使用String.getBytes()一样。它使用恰好是 JVM 的默认值的任何随机编码。所以它只有在你幸运的情况下才有效。
【解决方案2】:

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

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

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

【讨论】:

  • 附加以下行。 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  • .getBytes(StandardCharsets.UTF_8) 有点干净
【解决方案3】:

您可以创建一个环绕您的 OutputStream 的 PrintStream,然后将其称为 print(String):

final OutputStream os = new FileOutputStream("/tmp/out");
final PrintStream printStream = new PrintStream(os);
printStream.print("String");
printStream.close();

【讨论】:

  • PrintStream 使用什么字符集转换为字节?
【解决方案4】:

By design是这样处理的:

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

【讨论】:

  • 请注意w.close() 也会关闭out
  • 我更喜欢这个答案,因为它提供了明确的编码规范!我建议使用现有的预定义编码,例如 StandardCharsets.UTF_8 而不是字符串文字(“UTF-8”)。
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    您可以使用Apache Commons IO:

    try (OutputStream outputStream = ...) {
        IOUtils.write("data", outputStream, "UTF-8");
    }
    

    【讨论】:

    • IOUtils.write(String data, OutputStream output, Charset encoding) 被实现为output.write(data.getBytes(Charsets.toCharset(encoding))),所以如果编码的字符串不能放入字节数组中,则可能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多