繁体   English   中英

Java String转换为十六进制

[英]Java String conversion to hex

我正在使用tcp / ip套接字侦听器,该侦听器在端口80上侦听来自远程主机的数据。 现在这些传入的数据是不可读的格式,因此我将这些传入的数据保存为最初的字符串,然后将该字符串转换为字符数组,然后对于数组中的每个索引,我都将其内容转换为十六进制。 现在的问题是,数据正好转换为十六进制,但是在某些地方转换不正确,因此十六进制部分为'fffd'。 在结果十六进制应为'bc'(0xBC)的位置,则为'fffd'(0xFF 0xFD)。 我不得不相信Java程序无法正确读取传入数据的某些部分。 我使用BufferefInputStream和InputStreamReader读取传入的数据,并按以下方式检查流的结尾。

  BufferedInputStream is = new BufferedInputStream(connection.getInputStream());
  InputStreamReader isr = new InputStreamReader(is);
  while(isr.read()!=-1)

 {
 ...
}

其中“连接”是套接字对象。

我通过套接字获得的输入数据是#SR,IN-0002005,10:49:37,16 / 01/2010,$ <49X™™š@(bN>™™šBB©:4äý01300>ÀäCåKöA÷ Л。

我的程序执行的十六进制转换在许多其他十六进制值应该存在的地方具有“ fffd”。 转换对于输入字符串的大约60%是正确的

任何关于为什么我的十六进制转换为何不正确的指示都将很有帮助。

我认为您不应该使用阅读器。 读取器用于读取字符,您似乎正在使用二进制数据。 直接使用InputStream并在接收字节时转换字节。 java中的char是Unicode字符,我猜这是您问题的根源。

Java字符串不像处理VB(或大多数其他语言)那样容易“滥用”处理透明二进制数据。 VB在内部将字符串视为字节数组,而在Java中,字符串是字符的有序列表。

在您的情况下,您可以使用InputStreamReader包装InputStream,从而在将InputStream传递的字节转换为InputStreamReader传递的字符时使用平台的默认字符编码。 一些最常用的ISO 8859-X字符集未使用0x00到0x1f和0x7f到0xbf范围内的字节,因此,如果使用这种编码并从这些范围中读取字节,InputStreamReader将返回“替换字符” “,代码点为0xfffd,表示未知字符。

唯一“正确”的方法是省去InputStreamReader并将字节数组用于二进制数据。

当使用InputStreamReader将字节转换为char时,编码会产生巨大的不同:

  public static void main(String[] args) throws Exception {
    checkEncoding("ISO-8859-1");
    checkEncoding("ISO-8859-9");
    checkEncoding("Windows-1252");
    checkEncoding("UTF-8");
    checkEncoding("UTF-16BE");
    checkEncoding("Big5");
    checkEncoding("Shift-JIS");
  }

  private static void checkEncoding(String encoding) throws IOException {
    byte[] all = new byte[256];
    for ( int i = 0; i < all.length; ++i ) all[i] = (byte) i;
    ByteArrayInputStream bais = new ByteArrayInputStream(all);
    InputStreamReader isr = new InputStreamReader(bais, encoding);
    char[] ca = new char[256];
    int read = isr.read(ca);
    System.out.println(encoding + ":" + read);
    for ( int i = 0; i < read; ++i ) {
      if ( ca[i] != i ) {
        System.out.println(Integer.toHexString(i) + "->" + 
            Integer.toHexString(ca[i]));
      }
    }
  }

唯一可以“按预期”工作的是ISO-8859-1,它被定义为Unicode中的前256个字符。 ISO-8859-9和Windows-1252也产生1对1字符; 8859-9有几个不同的字符,但是1252有几个0xFFFD。

由于字节的排列方式,对于UTF-8,0x7F之后的所有内容都不好。 当然,您获得UTF-16字符的一半,而其他多字节编码则一团糟。

出于开发目的,请查看Eclipse中已与那些带有服务器连接器的Web容器一起使用的容器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM