我正在 Google 应用引擎中编写一个网络应用程序。它允许人们基本上编辑作为 .html
文件存储在 blobstore 中的 html 代码。
我正在使用 fetchData 返回文件中所有字符的 byte[]
。我正在尝试打印到 html 以便用户编辑 html 代码。一切都很好!
这是我现在唯一的问题:
字节数组在转换回字符串时存在一些问题。智能引号和几个字符看起来很时髦。 (?或日文符号等)具体来说,我看到的几个字节具有导致问题的负值。
智能引号在字节数组中返回为 -108
和 -109
。为什么会这样?如何解码负字节以显示正确的字符编码?
InputStream
,然后输入 byte[]
。现在,当我尝试将 byte[]
转换为字符串(我需要使用响应体进行攻击)时,我得到了非常有趣的字符,其中充满了智能引号和问号等等。我相信你的问题和我的一样,因为我们都在处理 byte[]
中的 html
。你能请教吗?
String str=new String(buffer, "Cp1252");
但没有帮助。
字节数组包含特殊编码的字符(您应该知道)。将其转换为字符串的方法是:
String decoded = new String(bytes, "UTF-8"); // example for one encoding type
顺便说一下 - 原始字节可能会显示为负小数,因为 java 数据类型 byte
是有符号的,它涵盖了从 -128 到 127 的范围。
-109 = 0x93: Control Code "Set Transmit State"
值 (-109) 是 UNICODE 中不可打印的控制字符。因此 UTF-8 不是该字符流的正确编码。
“Windows-1252”中的 0x93
是您要查找的“智能引用”,因此该编码的 Java 名称是“Cp1252”。下一行提供了一个测试代码:
System.out.println(new String(new byte[]{-109}, "Cp1252"));
Java 7 及以上
您还可以将所需的编码作为 StandardCharsets 中的 Charset
常量传递给 String
构造函数。正如其他答案中所建议的,这可能比将编码作为 String
传递更安全。
例如,对于 UTF-8 编码
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
你可以试试这个。
String s = new String(bytearray);
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();
}
}
输出
65
65
A
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
}
read
引发异常,此代码将泄漏资源。
我建议Arrays.toString(byte_array);
这取决于你的目的。例如,我想保存一个字节数组,与您在调试时看到的格式完全相同:[1, 2, 3]
如果您想保存完全相同的值而不将字节转换为字符格式,Arrays.toString (byte_array)
可以这个,。但是如果你想保存字符而不是字节,你应该使用 String s = new String(byte_array)
。在这种情况下,s
等价于字符格式的 [1, 2, 3]
。
Andreas_D 之前的回答很好。我只是要补充一点,无论您在哪里显示输出,都会有字体和字符编码,它可能不支持某些字符。
要确定是 Java 还是您的显示器有问题,请执行以下操作:
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。
byte
数据类型已签名。 “负”值只是具有最高有效字节集的字节。他还解释了您应该使用的最可能的字符集是 Windows-1252。不过,您应该知道从上下文或约定中使用什么字符集,而不必猜测。