有没有一种简单的方法可以避免处理文本编码问题?
有没有一种简单的方法可以避免处理文本编码问题?
Answers:
您确实无法避免处理文本编码问题,但是Apache Commons中已有一些解决方案:
Reader
至InputStream
:ReaderInputStream
Writer
至OutputStream
:WriterOutputStream
您只需要选择所需的编码即可。
如果从字符串开始,还可以执行以下操作:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
ReaderInputStream
实现将需要较少的内存-无需一次将所有字节存储在数组中。
好吧,阅读器处理字符,而InputStream处理字节。编码指定了您希望如何以字节表示字符,因此您不能真正忽略该问题。至于避免问题,我的看法是:选择一个字符集(例如“ UTF-8”)并坚持下去。
关于如何实际执行,正如已经指出的那样,“ 这些类的明显名称是ReaderInputStream和WriterOutputStream。 ”令人惊讶的是,即使“相反”类InputStreamReader和OutputStreamWriter 是 “相反”的类,它们也不包含在Java库中。包括在内。
因此,很多人都提出了自己的实现,包括Apache Commons IO。根据许可问题,您可能可以在项目中包含commons-io库,甚至可以复制部分源代码(可在此处下载)。
如您所见,这两个类的文档都指出“正确处理了JRE支持的所有字符集编码”。
注意:这里对其他答案之一的评论提到了此错误。但这会影响Apache Ant ReaderInputStream类(此处),而不影响 Apache Commons IO ReaderInputStream类。
还要注意,如果您以String开头,则可以使用Commons IO的 org.apache.commons.io.IOUtils跳过创建StringReader并一步一步创建InputStream的方法,如下所示:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
当然,您仍然需要考虑文本编码,但是至少转换是一步完成的。
new ByteArrayInputStream(report.toString().getBytes("utf-8"))
可以做到,这涉及在内存中分配报告的两个附加副本。如果报告很大,那就不好。看我的答案。
用:
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
这种方式不需要先转换为String
,然后再转换为byte[]
,在报表较大的情况下会分配更多的堆内存。直接从StringBuffer读取流时,它将即时转换为字节。
它使用来自Apache Commons IO项目的CharSequenceInputStream。
这些类的明显名称是ReaderInputStream和WriterOutputStream。不幸的是,这些未包含在Java库中。但是,谷歌是你的朋友。
我不确定它能否解决所有噩梦般的文本编码问题。
有一个RFE,但已关闭,无法解决。
您无法避免文本编码问题,但是Apache commons-io具有
请注意,这些是彼得在koders.com的答案中提及的库,只是链接到库而不是源代码。
你们是不是写的内容Reader
到OutputStream
?如果是这样,您将有一个更轻松的时间将包裹OutputStream
在OutputStreamWriter
并将char
s从写入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
您可以使用Cactoos(没有静态方法,只有对象):
您也可以采用其他方式进行转换:
用于仅使用java提供的内容读取流中的字符串。
InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));