如何在Java中将字符串与UTF8字节数组之间来回转换

如何在Java中将字符串与UTF8字节数组之间来回转换

How to convert Strings to and from UTF8 byte arrays in Java

在Java中,我有一个String,我想将其编码为字节数组(采用UTF8或其他某种编码)。 另外,我有一个字节数组(采用某种已知的编码),我想将其转换为Java String。 我如何进行这些转换?


从String转换为byte []:

1
2
String s ="some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);

从byte []转换为String:

1
2
byte[] b = {(byte) 99, (byte)97, (byte)116};
String s = new String(b, StandardCharsets.US_ASCII);

当然,您应该使用正确的编码名称。我的示例使用了两种最常见的编码US-ASCII和UTF-8。


这是一种避免每次转换都执行Charset查找的解决方案:

1
2
3
4
5
6
7
8
9
10
11
import java.nio.charset.Charset;

private final Charset UTF8_CHARSET = Charset.forName("UTF-8");

String decodeUTF8(byte[] bytes) {
    return new String(bytes, UTF8_CHARSET);
}

byte[] encodeUTF8(String string) {
    return string.getBytes(UTF8_CHARSET);
}


1
2
String original ="hello world";
byte[] utf8Bytes = original.getBytes("UTF-8");

您可以直接通过String(byte [],String)构造函数和getBytes(String)方法进行转换。 Java通过Charset类公开可用的字符集。 JDK文档列出了支持的编码。

90%的时间,此类转换是在流上执行的,因此您将使用Reader / Writer类。您不会在任意字节流上使用String方法来进行增量解码-您可能会遇到涉及多字节字符的错误。


我的tomcat7实现接受的字符串为ISO-8859-1;尽管HTTP请求的内容类型。当尝试正确解释'é'等字符时,以下解决方案对我有用。

1
2
3
4
5
byte[] b1 = szP1.getBytes("ISO-8859-1");
System.out.println(b1.toString());

String szUT8 = new String(b1,"UTF-8");
System.out.println(szUT8);

尝试将字符串解释为US-ASCII时,未正确解释字节信息。

1
2
b1 = szP1.getBytes("US-ASCII");
System.out.println(b1.toString());

或者,可以使用Apache Commons的StringUtils。

1
2
 byte[] bytes = {(byte) 1};
 String convertedString = StringUtils.newStringUtf8(bytes);

要么

1
2
 String myString ="example";
 byte[] convertedBytes = StringUtils.getBytesUtf8(myString);

如果您具有非标准字符集,则可以相应地使用getBytesUnchecked()或newString()。


为了将一系列字节解码为正常的字符串消息,我终于使用以下代码将其与UTF-8编码一起使用:

1
2
3
4
5
6
7
8
9
10
11
12
/* Convert a list of UTF-8 numbers to a normal String
 * Usefull for decoding a jms message that is delivered as a sequence of bytes instead of plain text
 */

public String convertUtf8NumbersToString(String[] numbers){
    int length = numbers.length;
    byte[] data = new byte[length];

    for(int i = 0; i< length; i++){
        data[i] = Byte.parseByte(numbers[i]);
    }
    return new String(data, Charset.forName("UTF-8"));
}

如果您使用的是7位ASCII或ISO-8859-1(一种非常常见的格式),则根本不必创建新的java.lang.String。只需将字节转换为char即可,其性能要高得多:

完整的工作示例:

1
2
3
4
for (byte b : new byte[] { 43, 45, (byte) 215, (byte) 247 }) {
    char c = (char) b;
    System.out.print(c);
}

如果您不使用扩展字符,例如?,?,?,?,?,ê,并且可以确保仅传输的值是前128个Unicode字符,那么此代码也适用于UTF-8和扩展ASCII (如cp-1252)。


1
2
3
4
5
6
7
8
9
Charset UTF8_CHARSET = Charset.forName("UTF-8");
String strISO ="{"name":"?"}";
System.out.println(strISO);
byte[] b = strISO.getBytes();
for (byte c: b) {
    System.out.print("[" + c +"]");
}
String str = new String(b, UTF8_CHARSET);
System.out.println(str);

我无法发表评论,但不想启动新线程。但这是行不通的。一个简单的往返:

1
2
3
byte[] b = new byte[]{ 0, 0, 0, -127 };  // 0x00000081
String s = new String(b,StandardCharsets.UTF_8); // UTF8 = 0x0000, 0x0000,  0x0000, 0xfffd
b = s.getBytes(StandardCharsets.UTF_8); // [0, 0, 0, -17, -65, -67] 0x000000efbfbd != 0x00000081

在编码之前和之后,我需要b []相同的数组,而不是(该数组引用第一个答案)。


1
2
3
4
Reader reader = new BufferedReader(
    new InputStreamReader(
        new ByteArrayInputStream(
            string.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));


1
2
3
4
5
6
7
8
9
//query is your json  

 DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpPost postRequest = new HttpPost("http://my.site/test/v1/product/search?qy=");

 StringEntity input = new StringEntity(query,"UTF-8");
 input.setContentType("application/json");
 postRequest.setEntity(input);  
 HttpResponse response=response = httpClient.execute(postRequest);

太晚了,但我刚遇到这个问题,这是我的解决办法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static String removeNonUtf8CompliantCharacters( final String inString ) {
    if (null == inString ) return null;
    byte[] byteArr = inString.getBytes();
    for ( int i=0; i < byteArr.length; i++ ) {
        byte ch= byteArr[i];
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        if ( !( (ch > 31 && ch < 253 ) || ch == '\t' || ch == '
'
|| ch == '
'
) ) {
            byteArr[i]=' ';
        }
    }
    return new String( byteArr );
}


推荐阅读

    linux输出字符串命令?

    linux输出字符串命令?,标准,基础,字符串,资料,简介,商业,数字,系统,命令,汉

    linux命令删除字符串?

    linux命令删除字符串?,软件,系统,代码,名称,通用,连续,字符,字符串,命令,空

    linux转换字符集命令?

    linux转换字符集命令?,系统,名称,时间,位置,服务,文件,字符集,命令,格式,以

    linux设置编码命令?

    linux设置编码命令?,系统,数据,发展,文件,字符集,命令,数据库,以下,终端,大

    字符串查找命令linux?

    字符串查找命令linux?,系统,字符串,工具,信息,文件,命令,字符,选项,文本,范

    linux命令替换字符串?

    linux命令替换字符串?,字符串,文件,批量,首次,数据,命令,内容,方法,用字,结

    linux拼接字符串命令?

    linux拼接字符串命令?,系统,工作,代码,工具,名称,信息,地址,时间,数据,命令,l

    linux地址转换命令是?

    linux地址转换命令是?,地址,系统,代码,密码,网络,信息,服务,电脑,设备,报告,

    linux命令看文件编码?

    linux命令看文件编码?,状态,系统,文件,工具,名称,数据,命令,格式,汉字,以下,L

    添加字符串命令linux?

    添加字符串命令linux?,情况,名称,文件,位置,名字,地方,连续,信息,命令,内容,L

    linux命令时间转换?

    linux命令时间转换?,时间,系统,命令,信息,国家,大陆,概念,终端,时区,时分,Lin

    linux命令查找字符串?

    linux命令查找字符串?,工具,信息,命令,字符串,系统,工作,文件,范本,样式,文

    linux命令改变编码?

    linux命令改变编码?,系统,文件,工作,代码,工具,命令,字符集,格式,以下,方式,l

    linux命令时间戳转换?

    linux命令时间戳转换?,时间,系统,地址,信息,工作,代码,标准,工具,形态,命令,l

    修改linux编码命令?

    修改linux编码命令?,系统,文件,命令,情况,标准,工作,格式,字符集,以下,方式,l

    linux转换行列命令?

    linux转换行列命令?,工作,地址,信息,网络,系统,命令,标准,电脑,环境,目录,lin

    linux地址转换命令?

    linux地址转换命令?,地址,系统,代码,信息,设备,网络,服务,密码,状态,报告,lin

    转换格式命令linux?

    转换格式命令linux?,系统,情况,地址,命令,设备,工作,基础,发行,工具,数据,Lin

    linux转换图形命令?

    linux转换图形命令?,系统,工作,密码,工具,地址,命令,地方,环境,软件,信息,Lin

    linux时间转换命令?

    linux时间转换命令?,时间,系统,国家,大陆,命令,信息,标准,电脑,时区,终端,lin