it-swarm.cn

如何将Reader转换为InputStream,将Writer转换为OutputStream?

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

85
Andrei Savu

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

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

42
Peter

如果您从String开始,您还可以执行以下操作:

new ByteArrayInputStream(inputString.getBytes("UTF-8"))
92
Ritesh Tendulkar

好吧,Reader处理字符,InputStream处理字节。编码指定了您希望如何将字符表示为字节,因此您无法真正忽略该问题。至于避免问题,我的意见是:选择一个字符集(例如“UTF-8”)并坚持下去。

关于如何实际操作,正如已经指出的那样,“这些类的明显名称是 ReaderInputStream WriterOutputStream ”令人惊讶的是,“这些不是包含在Java库中,即使'相反'类, InputStreamReaderOutputStreamWriter包含。

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

正如您所看到的,这两个类的文档都指出“JRE支持的所有字符集编码都得到了正确处理”。

注:这里提到的其他答案之一的评论 这个错误 。但这会影响Apache Ant ReaderInputStream类( here ),not Apache Commons IO ReaderInputStream类。

38
Peter Ford

另请注意,如果您开始使用String,则可以使用org.Apache.commons.io.IOUtils从 Commons IO 跳过创建StringReader并创建一个InputStream。像这样:

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

当然,您仍然需要考虑文本编码,但至少转换只需一步即可完成。

19
Phil Harvey

使用:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

这种方式不需要事先转换到String然后再转换到byte[],它会分配更多堆内存,以防报告很大。它会在从StringBuffer直接读取流时立即转换为字节。

它使用 CharSequenceInputStream 来自Apache Commons IO project。

8
Oliv
7
Bozho

您无法避免文本编码问题,但 Apache commons-io has

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

5
dfrankow

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

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

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

5
Tom Hawtin - tackline

您是否尝试将Reader的内容写入OutputStream?如果是这样,你将更容易将OutputStream包装在OutputStreamWriter中,并将chars从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
4
Sam Barnum

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

你也可以转换其他方式:

1
yegor256

使用WriterOutputStream时出现警告 - 它并不总是能够正确地将二进制数据写入文件/与常规输出流相同。我有一个问题,花了我一段时间追查。

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

1
romeara