我需要将InputStream的内容转换为String。这里的难点是输入编码,即Latin-1。我尝试了几种方法和代码片段,包括String,getBytes,char []等,以便直接获得编码,但似乎没有任何效果。
最后,我想出了下面的工作解决方案。但是,这个代码对我来说似乎有点冗长,即使对于Java也是如此。所以这里的问题是:
是否有更简单,更优雅的方法来实现此处所做的工作?
private String convertStreamToStringLatin1(java.io.InputStream is)
throws IOException {
String text = "";
// setup readers with Latin-1 (ISO 8859-1) encoding
BufferedReader i = new BufferedReader(new InputStreamReader(is, "8859_1"));
int numBytes;
CharBuffer buf = CharBuffer.allocate(512);
while ((numBytes = i.read(buf)) != -1) {
text += String.copyValueOf(buf.array(), 0, numBytes);
buf.clear();
}
return text;
}
答案 0 :(得分:7)
首先,对你已经采取的方法提出了一些批评。当您只需要CharBuffer
时,不应该不必要地使用NIO char[512]
。每次迭代都不需要clear
缓冲区。
int numBytes;
final char[] buf = new char[512];
while ((numBytes = i.read(buf)) != -1) {
text += String.copyValueOf(buf, 0, numBytes);
}
您还应该知道只有constructing a String
这些参数会产生相同的效果,因为构造函数也会复制数据。
复制子阵列的内容;后续修改字符数组不会影响新创建的字符串。
您可以使用动态ByteArrayOutputStream
来增加内部缓冲区以容纳所有数据。然后,您可以使用byte[]
中的整个toByteArray
解码为String
。
优点是推迟解码直到最后避免单独解码片段;虽然这可能适用于像ASCII或ISO-8859-1这样的简单字符集,但它不可以在UTF-8和UTF-16等多字节方案上工作。这意味着将来更容易更改字符编码,因为代码不需要修改。
private static final String DEFAULT_ENCODING = "ISO-8859-1";
public static final String convert(final InputStream in) throws IOException {
return convert(in, DEFAULT_ENCODING);
}
public static final String convert(final InputStream in, final String encoding) throws IOException {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final byte[] buf = new byte[2048];
int rd;
while ((rd = in.read(buf, 0, 2048) >= 0) {
out.write(buf, 0, rd);
}
return new String(out.toByteArray(), 0, encoding);
}
答案 1 :(得分:2)
我看不出它会变得多么简单。我曾经这样做过一次......如果你已经有了一个字符串,你可以这样做:
new String(originalString.getBytes(), "ISO-8859-1");
这样的事情也可以起作用:
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
return new String(sb.toString().getBytes(), "ISO-8859-1");
编辑:我应该补充一点,这实际上只是您已经在工作的解决方案的替代方案。当谈到在Java中转换Streams时,它不会简单得多,所以去吧。 :)
答案 2 :(得分:0)
如果你不想自己探测,你可以看看项目中的apache commons IOUtils.toString(InputStream input, String encoding),它似乎可以做你想要的。我自己没有尝试过该方法,但是java doc声明“使用指定的字符编码将InputStream的内容作为String获取。”
答案 3 :(得分:0)
Guava的IO包非常好用。
Files.toString(yourFile, CharSets.ISO_8859_1)
或来自流
new String(ByteStreams.toByteArray(stream), CharSets.ISO_8859_1)
答案 4 :(得分:0)
我刚发现问题this answer的Read/convert an InputStream to a String可以应用于我的问题,请参阅下面的代码。无论如何,我非常感谢你到目前为止给出的答案。
private String convertStreamToString(InputStream is, String charsetName) {
try {
return new java.util.Scanner(is, charsetName).useDelimiter("\\A").next();
} catch (java.util.NoSuchElementException e) {
return "";
}
}
因此,为了从Latin-1编码,请将其命名为:
String message = convertStreamToString(is, "8859_1");