java - 将 InputStream 的 Latin-1 内容转换为 UTF-8 字符串

标签 java string character-encoding inputstream

我需要将 InputStream 的内容转换为字符串。这里的难点在于输入编码,即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;
}

最佳答案

首先,对您已经采用的方法提出一些批评。当您只需要一个 char[512] 时,您不应该不必要地使用 NIO CharBuffer。您也不需要每次迭代都清除缓冲区。

int numBytes;
final char[] buf = new char[512];
while ((numBytes = i.read(buf)) != -1) {
    text += String.copyValueOf(buf, 0, numBytes);
}

你还应该知道,只是constructing a String使用这些参数将产生相同的效果,因为构造函数也会复制数据。

The contents of the subarray are copied; subsequent modification of the character array does not affect the newly created string.


您可以使用动态 ByteArrayOutputStream它会增加一个内部缓冲区来容纳所有数据。然后,您可以使用 toByteArray 中的整个 byte[] 解码成 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);
}

关于java - 将 InputStream 的 Latin-1 内容转换为 UTF-8 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11854794/

相关文章:

java - 在运行时包装方法调用

java - 谁能推荐一个可编写脚本的 Java 分析器?

php - 存储数据的奇怪字符编码,旧脚本显示它们很好,新脚本却没有

python - 在另一个字符串中多次查找一个字符串 - Python

php - MySQL 不存储西里尔字符集

r -\SweaveInput{} 错误消息声称存在的文件不存在

java - Java中初始化可变Set的便捷方法

java - 在 fragment 中使用数据库

string - Kotlin - 是否有一个基本函数可以用引用字符串中的多个字符串替换多个字符串?

R 中的字符串拆分,具有复杂的除法