Java字节到字符转换

Java字节到字符转换,java,Java,我从TCP/IP套接字中读取: byte[] bbuf = new byte[30]; s.getInputStream().read(bbuf); for (int i = 0; i < bbuf.length; i++) { System.out.println(Integer.toHexString( (int) (bbuf[i] & 0xff))); } byte[]bbuf=新字节[30]; s、 getInputStream().read(bbuf); fo

我从TCP/IP套接字中读取:

byte[] bbuf = new byte[30];
s.getInputStream().read(bbuf);
for (int i = 0; i < bbuf.length; i++)
{
     System.out.println(Integer.toHexString( (int) (bbuf[i] & 0xff)));
}
byte[]bbuf=新字节[30];
s、 getInputStream().read(bbuf);
for(int i=0;i
这输出CA 68 9F 75,这是我所期望的。现在我想用chars来代替

char[] cbuf = new char[30];
BufferedReader input =  new BufferedReader(new InputStreamReader(s.getInputStream())); 
for (int i = 0; i < cbuf.length; i++)
{
     System.out.println(Integer.toHexString( (int) (cbuf[i] )));
}
char[]cbuf=新字符[30];
BufferedReader input=新的BufferedReader(新的InputStreamReader(s.getInputStream());
for(int i=0;i
现在输出为CA6817875。因此,第三个字节(并且只有第三个字节)起作用。我假设它与字符集有关,并且我必须在InputStreamer中指定一个字符集。我不知道如何找出我必须使用的字符集。第二,我很惊讶,如果是因为角色集,我只得到一个角色的混乱。我尝试了所有其他的角色,但这似乎是我能找到的唯一一个


谁能解开这个谜团?

InputStreamReader将使用。因为您没有明确指定应该使用什么字符编码,所以它将使用系统的默认字符编码

字节的转换方式取决于所使用的字符编码

如果数据是二进制数据,并且不表示使用某些字符编码的文本,则使用
InputStreamReader
读取此数据是错误的


另请参见:

InputStreamReader
将使用。因为您没有明确指定应该使用什么字符编码,所以它将使用系统的默认字符编码

字节的转换方式取决于所使用的字符编码

如果数据是二进制数据,并且不表示使用某些字符编码的文本,则使用
InputStreamReader
读取此数据是错误的


另请参见:

您的问题是您正在比较梨和苹果;字节与字符不同。在代码中,字符Ÿ用以下方式表示:

  • 9F(字节使用Windows-1252编码)
  • 178(char使用UTF-16编码,这是Java在内部始终用于字符的编码)
为了证明我所说的,请检查以下内容:

String myString = "Caña";
byte[] bbuf = myString.getBytes();     // [ 43, 61, C3, B1, 61 ]   (UTF-8 on my machine)
char[] cbuf = myString.toCharArray();  // [ 43, 61, F1, 61 ]  (Java uses UTF-16 internally)
下面是对您的问题的分析:

  • 您从字符串中获取了一个字节数组,我猜是这样做的:
    myString.getBytes()
    由于您没有指定编码,系统在您的计算机(Windows-1252)中使用默认值

  • 当您使用InputSteanReader等将字节读入字符串时,实际上没有问题,因为您是从另一台(或同一台)Windows机器上读取的,问题是当您得到字符数组(而不是字节数组)时,希望得到相同的结果(使用
    myString.getBytes()
    而不是
    myString.tocharray()
    ,您将正确地看到您的字节)

最后,一些建议:

  • 在字符串和字节数组之间转换时,始终明确声明编码:

    byte[] bbuf = myString.getBytes(Charset.forName("UTF-8"));
    
    String myString = new String(bbuf, Charset.forName("UTF-8"));
    
  • 永远不要混合字符和字节,它们是不同的


    • 你的问题是你在比较梨和苹果;字节与字符不同。在代码中,字符Ÿ用以下方式表示:

      • 9F(字节使用Windows-1252编码)
      • 178(char使用UTF-16编码,这是Java在内部始终用于字符的编码)
      为了证明我所说的,请检查以下内容:

      String myString = "Caña";
      byte[] bbuf = myString.getBytes();     // [ 43, 61, C3, B1, 61 ]   (UTF-8 on my machine)
      char[] cbuf = myString.toCharArray();  // [ 43, 61, F1, 61 ]  (Java uses UTF-16 internally)
      
      下面是对您的问题的分析:

      • 您从字符串中获取了一个字节数组,我猜是这样做的:
        myString.getBytes()
        由于您没有指定编码,系统在您的计算机(Windows-1252)中使用默认值

      • 当您使用InputSteanReader等将字节读入字符串时,实际上没有问题,因为您是从另一台(或同一台)Windows机器上读取的,问题是当您得到字符数组(而不是字节数组)时,希望得到相同的结果(使用
        myString.getBytes()
        而不是
        myString.tocharray()
        ,您将正确地看到您的字节)

      最后,一些建议:

      • 在字符串和字节数组之间转换时,始终明确声明编码:

        byte[] bbuf = myString.getBytes(Charset.forName("UTF-8"));
        
        String myString = new String(bbuf, Charset.forName("UTF-8"));
        
      • 永远不要混合字符和字节,它们是不同的


      我不知道这里是否有副作用,但我这样做:

      buf = new String(buffer, StandardCharsets.ISO_8859_1).toCharArray();
      
      其中“buffer”是从GZIPInputStream读取的字节数组。
      这只是对莫尔加诺上述解释的扩展。

      我不知道这里是否有任何副作用,但我这样做:

      buf = new String(buffer, StandardCharsets.ISO_8859_1).toCharArray();
      
      其中“buffer”是从GZIPInputStream读取的字节数组。
      这只是莫尔加诺上述解释的扩展。

      您需要知道字符是如何编码的。我会尝试
      UTF-8
      而不是从默认编码开始。您需要知道字符是如何编码的。我会尝试使用
      UTF-8
      而不是您的默认编码作为开始。我更改了编码以使用StandardCharset,因为这样可以提供更好的平台稳定性。我更改了编码以使用StandardCharset,因为这样可以提供更好的平台稳定性。