byte和char的getbytes问题请教高手

angry_pig 2010-04-21 01:20:07
欲在字符串前加入一个头字节标识字符串长度。

String str = "Test" ;
str = (char)(str.length()) + str;

byte[] b = str.getbytes();



然后打印 b按16进制的数值 得到的是 04 54 65 73 74 ,直接打印str 是 :Test
这是没有问题的

现在


String str = "https://forum.csdn.net/PointForum/Forum/PostTopic.aspx?forumID=3d11cb76-8373-401d-9e9a-a6b24dd73eff3d11cb76-8373-401d-9e9a-a6b24dd73eff" ; //现在长度是134 = 0x86,大于0x7F

str = (char)(str.length()) + str;

byte[] b = str.getbytes();



现在直接打印str,是这样的:
†https://forum.csdn.net/PointForum/Forum/PostTopic.aspx?forumID=3d11cb76-8373-401d-9e9a-a6b24dd73eff3d11cb76-8373-401d-9e9a-a6b24dd73eff

没问题好象,但是看b的十六进制数据成这样的了:

81 30 81 36 68 74 74 70 3A 2F 2F 66 6F 72 75 .........
http是从第五个68 74 74 70后开始的,也就是说 0x86 这个字符被getbytes成了 81 30 81 36

实在很难理解,getbytes后,0x86这个8位的怎么就呼的一下给扩展到了32位呢?当然了,如果我手动强行转换还是可以的,(byte)0x86,这打印出来也确实是86,就是不知道在字符串中怎么构造才能把大于127的数按原数字进行传输呢?

...全文
251 13 打赏 收藏 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
angry_pig 2010-04-22
  • 打赏
  • 举报
回复
:) :) :)



String str = "https://forum.csdn.net/PointForum/Forum/PostTopic.a"
+ "spx?forumID=3d11cb76-8373-401d-9e9a-a6"
+ "b24dd73eff3d11cb76-8373-401d-9e9a-a6b24dd"
+ "73eff" ; //现在长度是134 = 0x86,大于0x7F

str = (char)(str.length()) + str;

byte[] b = str.getbytes("ISO-8895-1");


angry_pig 2010-04-22
  • 打赏
  • 举报
回复
收到,散分,谢谢大伙
hbgzg3006 2010-04-21
  • 打赏
  • 举报
回复
原因如下:
由于char是Unicode字符集,而getBytes windows下是gbk。而刚好你的长度字符串长度是Unicode编码中存在,但是在gbk中不存在的字符。所以java都解释成了?。你可以通过如下打印,看有多少是?

for(int i=128;i<256;i++){
byte[] bb=((char)i+"").getBytes();
for(byte b:bb){
System.out.println(b);
}
}

进一步说:
Unicode的上述段的字符集
http://www.nengcha.com/code/unicode/class/2/
从其中可以看出你的长度的字符是†
但是你在Eclipse中验证一下就知道,上述符号getBytes会提示你gbk不存在该字符的编码。如下。

char c='†';//
byte[] b = (c+"").getBytes();

解决办法:
byte[] b = ((char)str.length()+"").getBytes("unicode");
for(byte i:b){
if(i<0)
System.out.println(Integer.toHexString(i+256));
else
System.out.println(Integer.toHexString(i));
}
由于Unicode 采用的是big endian所以有两个字节的头(共四个字节),Unicode的编码都是两个字节,所以取后面两个字节即可。
chzhm159 2010-04-21
  • 打赏
  • 举报
回复
我是菜鸟
angry_pig 2010-04-21
  • 打赏
  • 举报
回复
3f ? 好象应该是86才对,唉,郁闷了
hbgzg3006 2010-04-21
  • 打赏
  • 举报
回复

3f 68 74 74 70 3a 2f 2f 66 6f 72 75 6d 2e 63 73 64 6e 2e 6e 65 74 2f 50 6f 69 6e 74 46 6f 72 75 6d 2f 46 6f 72 75 6d 2f 50 6f 73 74 54 6f 70 69 63 2e 61 73 70 78 3f 66 6f 72 75 6d 49 44 3d 33 64 31 31 63 62 37 36 2d 38 33 37 33 2d 34 30 31 64 2d 39 65 39 61 2d 61 36 62 32 34 64 64 37 33 65 66 66 33 64 31 31 63 62 37 36 2d 38 33 37 33 2d 34 30 31 64 2d 39 65 39 61 2d 61 36 62 32 34 64 64 37 33 65 66 66
hbgzg3006 2010-04-21
  • 打赏
  • 举报
回复

[code=Java]
我这里的运行结果是正确的
3f 68 74 74 70 3a 2f 2f 66
//楼主要注意getBytes的默认编码是根据系统编码改变的
[/code]
angry_pig 2010-04-21
  • 打赏
  • 举报
回复
硬塞进去结果 getbytes 出来 表示长度的字符 变成4个字节的了
angry_pig 2010-04-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bawgiitx 的回复:]

char,short 2字节16位
int 4字节32位

这样用,晕,都知道第一个是表示长度的你还转byte[]!!!!
int len=str.charAt(0);
byte[] b = str.substring(1).getbytes();
[/Quote]

有点明白大哥的意思了,大哥可能没明白我的意思:

字符串前面加个长度是自己定义的,而且还知道后边的长度不会超过255,这意思就是说我用一个字节肯定就能把长度表示出来了,然后把长度当作一个字符合进数据包里进行传输,就是这样子的了。

你写的是别人发过来的,让我们来处理。我说的是 双方约定好通信协议 然后进行交换数据,不光要处理字符串,还要合成字符串啊。

这个问题是出在合成上,呵呵。
bawgiitx 2010-04-21
  • 打赏
  • 举报
回复
char,short 2字节16位
int 4字节32位

这样用,晕,都知道第一个是表示长度的你还转byte[]!!!!
int len=str.charAt(0);
byte[] b = str.substring(1).getbytes();
beiouwolf 2010-04-21
  • 打赏
  • 举报
回复
byte带符号
char不带符号
angry_pig 2010-04-21
  • 打赏
  • 举报
回复
不对啊,要大于0x7F,6a是肯定没问题的,小于7F的都没事的
无辜的程序员 2010-04-21
  • 打赏
  • 举报
回复
我打出来的是:

6a 68 74 74 70 3a 2f 2f 66。。。

应该是你说的正常吧。。。。

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧