如何将Reader转换为InputStream和Writer到OutputStream?

有没有简单的方法来避免处理文本编码问题?

你不能真正避免处理文本编码问题,但有现有的解决scheme:

  • ReaderInputStreamReaderInputStream
  • WriterOutputStreamWriterOutputStream

你只需要select你select的编码。

如果你用一个string开始,你也可以执行以下操作:

 new ByteArrayInputStream(inputString.getBytes("UTF-8")) 

那么,Reader会处理字符,而InputStream会处理字节。 编码指定如何将字符表示为字节,因此您不能真正忽略该问题。 至于避免问题,我的意见是:挑一个字符集(如“UTF-8”),并坚持下去。

关于如何真正做到这一点,正如已经指出的,“ 这些类的显式名称是ReaderInputStreamWriterOutputStream”令人惊讶的是,即使“相反”类InputStreamReader和OutputStreamWriter 这些不包含在Java库中 ”包括在内。

所以,很多人提出了自己的实现,包括Apache Commons IO 。 根据许可问题,您可能会将commons-io库包含在您的项目中,甚至可能会复制部分源代码(可在此处下载)。

  • Apache ReaderInputStream: API / 源代码直接链接
  • Apache WriterOutputStream: API / 源代码直接链接

正如你所看到的,这两个类的文档声明“JRE支持的所有字符集编码都被正确处理”。

注意在这里的其他答案之一的评论提到这个错误 。 但是,这会影响Apache Ant ReaderInputStream类( 此处 ), 而不是 Apache Commons IO ReaderInputStream类。

还要注意的是,如果你从一个string开始,你可以跳过创build一个StringReader并使用Commons IO中的 org.apache.commons.io.IOUtils创build一个InputStream,如下所示:

 InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8"); 

当然,你仍然需要考虑文本编码,但至less转换是在一个步骤中发生的。

commons-io 2.0有WriterOutputStream

使用:

 new CharSequenceInputStream(html, StandardCharsets.UTF_8); 

这种方式不需要预先转换为String ,然后再转换为byte[] ,分配更多的堆内存,以防报告较大。 当stream被读取时,它会立即转换为字节,直接来自StringBuffer。

它使用Apache Commons IO项目中的CharSequenceInputStream 。

这些类的明显名称是ReaderInputStream和WriterOutputStream。 不幸的是,这些不包含在Java库中。 不过,谷歌是你的朋友。

我不确定它会解决所有的文本编码问题,这是噩梦。

有一个RFE,但它已closures,不会修复。

你是否试图将Reader的内容写入OutputStream ? 如果是这样,你将有一个更容易的时间包装OutputStreamOutputStreamWriter并从Reader写入到Writer ,而不是试图将读者转换为InputStream

 final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) ); int charsRead; char[] cbuf = new char[1024]; while ((charsRead = data.read(cbuf)) != -1) { writer.write(cbuf, 0, charsRead); } writer.flush(); // don't forget to close the writer in a finally {} block 

你不能避免文本编码问题,但Apache公用事业有

  • ReaderInputStream
  • WriterOutputStream

注意这些是在Peter的koders.com的回答中提到的库,只是链接到库而不是源代码。

使用WriterOutputStream时的警告 – 它并不总是将二进制数据正确地写入文件,就像正常的输出stream一样。 我有一个问题,这花了我一段时间来追查。

如果可以的话,我build议使用一个输出stream作为你的基础,如果你需要编写string,可以使用一个OUtputStreamWriter封装来实现。 将文本转换为字节比其他方式更可靠,这可能是为什么WriterOutputStream不是标准Java库的一部分

你可以使用Cactoos (没有静态方法,只有对象):

  • new InputStreamOf(reader)
  • new OutputStreamTo(writer)

你也可以用其他方式转换:

  • new ReaderOf(inputStream)
  • new WriterTo(outputStream)

用于读取stream中的string,只需使用Java提供的东西。

 InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));