【问题标题】:UTF-8 byte[] to StringUTF-8 字节 [] 到字符串
【发布时间】:2012-01-20 16:17:05
【问题描述】:

假设我刚刚使用 BufferedInputStream 将 UTF-8 编码文本文件的字节读入字节数组。我知道我可以使用以下例程将字节转换为字符串,但是有没有比仅遍历字节并转换每个字节更有效/更智能的方法呢?

public String openFileToString(byte[] _bytes)
{
    String file_string = "";

    for(int i = 0; i < _bytes.length; i++)
    {
        file_string += (char)_bytes[i];
    }

    return file_string;    
}

【问题讨论】:

  • 你为什么不能这样做String fileString = new String(_bytes,"UTF-8");
  • 或者,您可以使用 BufferedReader 读取 char 数组。
  • @CoolBeans 如果我知道这样做,我可以这样做;)谢谢。
  • 您提供的 cide 解码 UTF-8。它不处理 任何 需要多个字节的代码点。

标签: java utf-8


【解决方案1】:

查看String的构造函数

String str = new String(bytes, StandardCharsets.UTF_8);

如果你觉得懒惰,可以使用Apache Commons IO 库直接将 InputStream 转换为 String:

String str = IOUtils.toString(inputStream, StandardCharsets.UTF_8);

【讨论】:

  • 或者 Guava 的 Charsets.UTF_8,如果你的 JDK 版本早于 1.7
  • 如果你的 Android API 低于 19,请使用 Guava 的 Charsets.UTF_8
  • 如果 checkstyle 说:“非法实例化:应该避免 java.lang.String 的实例化。”,然后呢?
  • 您可以在这里看到java.nio.charset.Charset.availableCharsets() 映射所有字符集,而不仅仅是StandardCharsets 中的字符集。如果你想使用其他字符集并且仍然想防止 String 构造函数抛出UnsupportedEncodingException,你可以使用java.nio.charset.Charset.forName()
  • IOUtils.toString(inputStream, StandardCharsets.UTF_8) 现已弃用。
【解决方案2】:

Java String 类具有用于将字节数组转换为字符串的内置构造函数。

byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};

String value = new String(byteArray, "UTF-8");

【讨论】:

    【解决方案3】:

    要转换 utf-8 数据,不能假设字节和字符之间存在 1-1 对应关系。 试试这个:

    String file_string = new String(bytes, "UTF-8");
    

    (呸。我发现我点击“发布您的答案”按钮的速度太慢了。)

    要将整个文件作为字符串读取,请执行以下操作:

    public String openFileToString(String fileName) throws IOException
    {
        InputStream is = new BufferedInputStream(new FileInputStream(fileName));
    
        try {
            InputStreamReader rdr = new InputStreamReader(is, "UTF-8");
            StringBuilder contents = new StringBuilder();
            char[] buff = new char[4096];
            int len = rdr.read(buff);
            while (len >= 0) {
                contents.append(buff, 0, len);
            }
            return buff.toString();
        } finally {
            try {
                is.close();
            } catch (Exception e) {
                // log error in closing the file
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以为此使用String(byte[] bytes) 构造函数。有关详细信息,请参阅此link编辑您还必须根据 java 文档考虑您的平台的默认字符集:

      通过使用解码指定的字节数组构造一个新的字符串 平台的默认字符集。新字符串的长度是 字符集的函数,因此可能不等于 字节数组。当给定字节时此构造函数的行为 在未指定的默认字符集中无效。这 CharsetDecoder 类应该在更多控制时使用 需要解码过程。

      【讨论】:

      • 如果您的字节不在平台的默认字符集中,您可以使用具有第二个Charset 参数的版本来确保转换正确。
      • @MikeDaniels 确实,我不想包括所有细节。刚刚编辑了我的答案
      【解决方案5】:

      您可以使用此问题中描述的方法(特别是因为您从 InputStream 开始):Read/convert an InputStream to a String

      特别是,如果您不想依赖外部库,可以尝试this answer,它通过InputStreamReaderInputStream 读入char[] 缓冲区并将其附加到StringBuilder .

      【讨论】:

        【解决方案6】:

        知道您正在处理一个 UTF-8 字节数组,您肯定会想要使用String constructor that accepts a charset name。否则,您可能会面临一些基于字符集编码的安全漏洞。请注意,它会抛出您必须处理的UnsupportedEncodingException。像这样的:

        public String openFileToString(String fileName) {
            String file_string;
            try {
                file_string = new String(_bytes, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                // this should never happen because "UTF-8" is hard-coded.
                throw new IllegalStateException(e);
            }
            return file_string;
        }
        

        【讨论】:

          【解决方案7】:

          这是一个以字节为单位读取并创建字符串的简化函数。它假定您可能已经知道文件的编码方式(否则为默认值)。

          static final int BUFF_SIZE = 2048;
          static final String DEFAULT_ENCODING = "utf-8";
          
          public static String readFileToString(String filePath, String encoding) throws IOException {
          
              if (encoding == null || encoding.length() == 0)
                  encoding = DEFAULT_ENCODING;
          
              StringBuffer content = new StringBuffer();
          
              FileInputStream fis = new FileInputStream(new File(filePath));
              byte[] buffer = new byte[BUFF_SIZE];
          
              int bytesRead = 0;
              while ((bytesRead = fis.read(buffer)) != -1)
                  content.append(new String(buffer, 0, bytesRead, encoding));
          
              fis.close();        
              return content.toString();
          }
          

          【讨论】:

          • 编辑代码以使默认值为 utf-8 以匹配 OP 的问题。
          【解决方案8】:

          String 有一个以 byte[] 和 charsetname 作为参数的构造函数:)

          【讨论】:

            【解决方案9】:

            这也涉及到迭代,但这比连接字符串要好得多,因为它们非常昂贵。

            public String openFileToString(String fileName)
            {
                StringBuilder s = new StringBuilder(_bytes.length);
            
                for(int i = 0; i < _bytes.length; i++)
                {
                    s.append((char)_bytes[i]);
                }
            
                return s.toString();    
            }
            

            【讨论】:

            • 我亲爱的主。 String str = new String(byte[]) 会很好。
            • 这提高了效率,但它不能正确解码 utf8 数据。
            【解决方案10】:

            为什么不从一开始就得到你正在寻找的东西并从文件中读取一个字符串而不是一个字节数组?比如:

            BufferedReader in = new BufferedReader(new InputStreamReader( new FileInputStream( "foo.txt"), Charset.forName( "UTF-8"));
            

            然后从 in 开始 readLine 直到完成。

            【讨论】:

            • 有时,保留原始行分隔符很有用。 OP 可能想要那个。
            【解决方案11】:

            我用这种方式

            String strIn = new String(_bytes, 0, numBytes);

            【讨论】:

            • 这没有指定字符集,所以你得到的平台默认字符集可能不是 UTF-8。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-05-31
            • 2014-03-07
            • 1970-01-01
            • 1970-01-01
            • 2015-09-01
            • 2020-09-15
            • 1970-01-01
            相关资源
            最近更新 更多