关于谷歌应用引擎:将字节数组转换为字符串(Java)

Converting byte array to String (Java)

我正在用谷歌应用引擎编写一个网络应用程序。它允许人们基本上编辑在blobstore中存储为.html文件的HTML代码。

我使用fetchdata返回文件中所有字符的byte[]。我试图打印到HTML,以便用户编辑HTML代码。一切都很好!

这是我现在唯一的问题:

字节数组在转换回字符串时遇到一些问题。聪明的引语和几个字符看起来很古怪。(?)s或日语符号等)具体来说,我看到的几个字节的值为负值,这导致了问题的发生。

智能引号在字节数组中以-108-109的形式出现。为什么会这样?如何解码负字节以显示正确的字符编码?


字节数组包含特殊编码的字符(您应该知道)。将其转换为字符串的方法是:

1
String decoded = new String(bytes,"UTF-8");  // example for one encoding type

顺便说一下,由于Java数据类型EDCOX1(0)的签名,原始字节出现可能是负小数,它覆盖范围从-128到127。

1
-109 = 0x93: Control Code"Set Transmit State"

值(-109)是Unicode中不可打印的控制字符。因此,UTF-8不是该字符流的正确编码。

"Windows 1252"中的EDOCX1 1是您所要查找的"智能报价",因此该编码的Java名称是"CP1252"。下一行提供测试代码:

1
System.out.println(new String(new byte[]{-109},"Cp1252"));


Java 7及以上

您还可以将所需的编码作为标准字符集的Charset常量传递给String构造函数。如其他答案所示,这可能比将编码作为String传递更安全。

例如,对于utf-8编码

1
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);


你可以试试这个。

1
String s = new String(bytearray);


1
2
3
4
5
6
7
8
9
10
11
public static String readFile(String fn)   throws IOException
{
    File f = new File(fn);

    byte[] buffer = new byte[(int)f.length()];
    FileInputStream is = new FileInputStream(fn);
    is.read(buffer);
    is.close();

    return  new String(buffer,"UTF-8"); // use desired encoding
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Main {

    /**
     * Example method for converting a byte to a String.
     */

    public void convertByteToString() {

        byte b = 65;

        //Using the static toString method of the Byte class
        System.out.println(Byte.toString(b));

        //Using simple concatenation with an empty String
        System.out.println(b +"");

        //Creating a byte array and passing it to the String constructor
        System.out.println(new String(new byte[] {b}));

    }

    /**
     * @param args the command line arguments
     */

    public static void main(String[] args) {
        new Main().convertByteToString();
    }
}

产量

1
2
3
65
65
A

我建议Arrays.toString(byte_array);

这取决于你的目的。例如,我希望保存一个字节数组,其格式与调试时看到的格式完全相同:[1, 2, 3]。如果要保存完全相同的值,而不将字节转换为字符格式,Arrays.toString (byte_array)会这样做。但如果要保存字符而不是字节,则应使用String s = new String(byte_array)。在这种情况下,s相当于[1, 2, 3]的字符格式。


安德烈亚斯·德之前的回答很好。我要补充的是,无论您在哪里显示输出,都会有一个字体和一个字符编码,它可能不支持某些字符。

要确定它是Java还是显示器是一个问题,请这样做:

1
2
3
4
    for(int i=0;i<str.length();i++) {
        char ch = str.charAt(i);
        System.out.println(i+" :"+ch+""+Integer.toHexString(ch)+((ch=='\ufffd') ?" Unknown character" :""));
    }

Java将任何无法理解的字符映射到未知字符的官方字符0xFFFD。如果你看到一个'?'在输出中,但它没有映射到0xFFFD,它是您的显示字体或编码,这是问题,而不是Java。