关于java:如何将Reader转换为InputStream,将Writer转换为OutputStream?

How to convert a Reader to InputStream and a Writer to OutputStream?

有没有一种简单的方法可以避免处理文本编码问题?


如果从字符串开始,还可以执行以下操作:

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


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

  • ReaderInputStreamReaderInputStream
  • WriterOutputStreamWriterOutputStream

您只需要选择您选择的编码。


好吧,读者处理字符,而输入流处理字节。编码指定您希望如何将字符表示为字节,因此不能真正忽略该问题。至于避免问题,我的观点是:选择一个字符集(例如"utf-8")并坚持使用它。

至于如何真正做到这一点,正如已经指出的,"这些类的明显名称是RealRePin流和WrreRealOutsStudio。"令人惊讶的是,"这些不包括在Java库中",即使包含"相反"类,也包括InputStreamReader和OuttoStaseWrror。

因此,很多人都有自己的实现,包括ApacheCommonsIO。根据许可问题的不同,您可能能够在项目中包含Commons IO库,甚至可以复制部分源代码(可在此处下载)。

  • apache readerinputstream:api/源代码直接链接
  • apache writeroutputstream:api/源代码直接链接

如您所见,两个类的文档都声明"JRE支持的所有字符集编码都得到了正确处理"。

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


另外请注意,如果您从一个字符串开始,您可以跳过创建一个StringReader,并使用来自Commons IO的org.apache.commons.io.ioutils在一个步骤中创建一个inputstream,如下所示:

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

当然,您仍然需要考虑文本编码,但至少转换是在一个步骤中进行的。


用途:

1
new CharSequenceInputStream(html, StandardCharsets.UTF_8);

这种方式不需要预先转换为String,然后转换为byte[],在报告很大的情况下,EDOCX1会分配更多的堆内存。当从StringBuffer读取流时,它会立即转换为字节。

它使用来自ApacheCommonsIO项目的CharSequenceinputstream。


commons io 2.0有WriterOutputStream


您不能避免文本编码问题,但是ApacheCommons IO有

  • 读卡器输入流
  • 写入组输出流

注意,这些是在peter's answer of koders.com中引用的库,只是指向库的链接,而不是源代码。


这些类的明显名称是readerinputstream和writeroutputstream。不幸的是,这些不包含在Java库中。然而,谷歌是你的朋友。

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

有一个RFE,但它已经关闭,无法修复。


你想把Reader的内容写到OutputStream上吗?如果是这样的话,您可以更轻松地将OutputStream包装在OutputStreamWriter中,并将charReader写入Writer,而不是尝试将读卡器转换为InputStream

1
2
3
4
5
6
7
8
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

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

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

您也可以反过来转换:

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

使用writeroutputstream时出现警告-它并不总是处理将二进制数据正确地/与常规输出流相同地写入文件。我有一个问题要花一段时间才能找到答案。

如果可以,我建议使用输出流作为基础,如果需要编写字符串,请在流周围使用OutputStreamWriter包装器来完成。将文本转换为字节比其他方式更可靠,这可能是为什么RealServutsPoSt流不是标准Java库的一部分。


使用Java提供的数据读取流中的字符串。

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