如何将Reader转换为InputStream和Writer到OutputStream?
有没有简单的方法来避免处理文本编码问题?
你不能真正避免处理文本编码问题,但有现有的解决scheme:
-
Reader
到InputStream
:ReaderInputStream
-
Writer
到OutputStream
:WriterOutputStream
你只需要select你select的编码。
如果你用一个string开始,你也可以执行以下操作:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
那么,Reader会处理字符,而InputStream会处理字节。 编码指定如何将字符表示为字节,因此您不能真正忽略该问题。 至于避免问题,我的意见是:挑一个字符集(如“UTF-8”),并坚持下去。
关于如何真正做到这一点,正如已经指出的,“ 这些类的显式名称是ReaderInputStream和WriterOutputStream” 。令人惊讶的是,即使“相反”类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
? 如果是这样,你将有一个更容易的时间包装OutputStream
在OutputStreamWriter
并从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")));