字节数组长度在转换前后变化
byte array length varies before and after transformation
我需要通过互联网(http restful 服务)发送和接收大字节数组。
我能想到的最简单的方法就是将字节数组转换成字符串。
我四处搜索,找到了这个 post Java Byte Array to String to Byte Array
我有以下代码来验证转换的准确性。
System.out.println("message");
System.out.println (message);
String message = "Die Strahlengriffelgewächse stammen...";
byte[] pack = Fbs.packExce(message);
System.out.println ("pack");
System.out.println (pack);
System.out.println ("packlenght:" + pack.length);
String toString = new String(pack);
System.out.println ("toString");
System.out.println (toString);
byte[] toBytes = toString.getBytes();
System.out.println ("toBytes");
System.out.println (toBytes);
System.out.println ("toByteslength:" +toBytes.length);
"Fbs.packExce()" 是一种接收大块字符串并生成大字节数组的方法。
我更改了消息的长度,在转换为字符串之前和转换回来之后检查并打印出字节数组的长度。
我得到了以下结果:
...
pack
[B@5680a178
packlenght:748
...
toBytes
[B@5fdef03a
toByteslength:750
----------------------
...
pack
[B@5680a178
packlenght:1016
...
toBytes
[B@5fdef03a
toByteslength:1018
我省略了 "message" 因为它太长了。
10 次中有 8 次,我可以看到派生的字节数组(新的,说 "toBytes")比原始字节长 2 个字节数组 ("pack")
我说的是10个中的8个,因为也有派生和原始长度相同的情况,见下文
...
pack
[B@5680a178
packlenght:824
toString
...
toBytes
[B@5fdef03a
toByteslength:824
...
我想不出确切的规则。
有人知道吗?
或者是否有更好的方法将字节数组与字符串相互转换?
干杯
the simplest way I can think of is to convert the byte array into string.
最简单的方法是错误的方法。对于大多数字符编码,将任意字节序列转换为文本很可能是有损的。
更好(即更健壮)的方法是使用 Base64 编码。阅读 javadoc Base64
class 及其依赖的编码和解码器 classes。
如果您坚持尝试使用 new String(byte[])
等方法将任意字节的首位字符转换回来:
请确保您选择的字符编码的字节 -> 字符 -> 字节转换序列无损。 (LATIN-1 可以)
编码/解码字符集不依赖当前执行平台的默认字符编码。
在客户端/服务器系统中,客户端和服务器必须使用相同的编码。
I have a need to send and receive large byte array over internet(http
restful service).
the simplest way I can think of is to convert the byte array into
string.
如果这只是关于使用 jaxrs 的 sending/receiving 字节数组,那么每个 jaxrs 实现都完全能够传输 byte[]
。参见 specification,第 4.2.4 节。
根据 Stephen C 的建议,我转向 Base64 basic 模式:
以下是我目前的完整验证码:
String message = "Die Strahlengriffelgewächse stammen ... ...
System.out.println("message");
System.out.println (message);
byte[] pack = Fbs.packExce(message);
System.out.println ("pack");
System.out.println (pack);
System.out.println ("packlenght:" + pack.length);
String toString = Base64.getEncoder().encodeToString(pack);
System.out.println ("toString");
System.out.println (toString);
byte[] toBytes = Base64.getDecoder().decode(toString);
System.out.println ("toBytes");
System.out.println (toBytes);
System.out.println ("toByteslength:" +toBytes.length);
String toBytesExtraction = extractExce(toBytes);
System.out.println ("toBytesExtraction");
System.out.println (toBytesExtraction);
String extraction = extractExce(pack);
System.out.println ("extraction");
System.out.println (extraction);
public static byte[] packExce(String text){
FlatBufferBuilder builder = new FlatBufferBuilder(0);
int textOffset = builder.createString(text);
Exce.startExce(builder);
Exce.addText(builder, textOffset);
int exce = Exce.endExce(builder);
Bucket.startBucket(builder);
Bucket.addContentType(builder, Post.Exce);
Bucket.addContent(builder, exce);
int buck = Bucket.endBucket(builder);
builder.finish(buck);
return builder.sizedByteArray();
//ByteBuffer buf = builder.dataBuffer();
//return buf;
//return Base64.getMimeEncoder().encodeToString(buf.array());
}
private String extractExce(byte[] bucket ){
String message = null;
ByteBuffer buf = ByteBuffer.wrap(bucket);
Bucket cont = Bucket.getRootAsBucket(buf);
System.out.println (cont.contentType());
if (cont.contentType() == Post.Exce){
message = ((Exce)cont.content(new Exce())).text();
}
return message;
}
这似乎对我有用:
...
pack
[B@5680a178
packlenght:2020
...
toBytes
[B@5fdef03a
toByteslength:2020
'''
----------------------
...
pack
[B@5680a178
packlenght:1872
...
toBytes
[B@5fdef03a
toByteslength:1872
...
并且分别从"toBytes"和"pack"中提取,忠实地还原了原来的"message"
String toBytesExtraction = extractExce(toBytes);
String extraction = extractExce(pack);
事实上,我没有提到的是我最初的实现是base64 mime。当时我的起点是 ByteBuffer(我现在是 byte[])。
如果您感兴趣,以下是我的代码片段。
编码器
...
ByteBuffer buf = builder.dataBuffer();
return Base64.getMimeEncoder().encodeToString(buf.array());
解码器
ByteBuffer buf = ByteBuffer.wrap(Base64.getMimeDecoder().decode(bucket));
我的猜测是问题可能来自 base64.mime。
因为我定位问题的第一步是去掉base64.mime,直接使用ByteBuffer。这是成功的...
嗯,我有点跑题了。
回到正题,关于字节数组在"new String(byte[]) and "String.getBytes()转换前后的“2字节变化”我还是一头雾水”...
干杯
我需要通过互联网(http restful 服务)发送和接收大字节数组。
我能想到的最简单的方法就是将字节数组转换成字符串。
我四处搜索,找到了这个 post Java Byte Array to String to Byte Array
我有以下代码来验证转换的准确性。
System.out.println("message");
System.out.println (message);
String message = "Die Strahlengriffelgewächse stammen...";
byte[] pack = Fbs.packExce(message);
System.out.println ("pack");
System.out.println (pack);
System.out.println ("packlenght:" + pack.length);
String toString = new String(pack);
System.out.println ("toString");
System.out.println (toString);
byte[] toBytes = toString.getBytes();
System.out.println ("toBytes");
System.out.println (toBytes);
System.out.println ("toByteslength:" +toBytes.length);
"Fbs.packExce()" 是一种接收大块字符串并生成大字节数组的方法。
我更改了消息的长度,在转换为字符串之前和转换回来之后检查并打印出字节数组的长度。
我得到了以下结果:
...
pack
[B@5680a178
packlenght:748
...
toBytes
[B@5fdef03a
toByteslength:750
----------------------
...
pack
[B@5680a178
packlenght:1016
...
toBytes
[B@5fdef03a
toByteslength:1018
我省略了 "message" 因为它太长了。
10 次中有 8 次,我可以看到派生的字节数组(新的,说 "toBytes")比原始字节长 2 个字节数组 ("pack")
我说的是10个中的8个,因为也有派生和原始长度相同的情况,见下文
...
pack
[B@5680a178
packlenght:824
toString
...
toBytes
[B@5fdef03a
toByteslength:824
...
我想不出确切的规则。
有人知道吗?
或者是否有更好的方法将字节数组与字符串相互转换?
干杯
the simplest way I can think of is to convert the byte array into string.
最简单的方法是错误的方法。对于大多数字符编码,将任意字节序列转换为文本很可能是有损的。
更好(即更健壮)的方法是使用 Base64 编码。阅读 javadoc Base64
class 及其依赖的编码和解码器 classes。
如果您坚持尝试使用 new String(byte[])
等方法将任意字节的首位字符转换回来:
请确保您选择的字符编码的字节 -> 字符 -> 字节转换序列无损。 (LATIN-1 可以)
编码/解码字符集不依赖当前执行平台的默认字符编码。
在客户端/服务器系统中,客户端和服务器必须使用相同的编码。
I have a need to send and receive large byte array over internet(http restful service).
the simplest way I can think of is to convert the byte array into string.
如果这只是关于使用 jaxrs 的 sending/receiving 字节数组,那么每个 jaxrs 实现都完全能够传输 byte[]
。参见 specification,第 4.2.4 节。
根据 Stephen C 的建议,我转向 Base64 basic 模式:
以下是我目前的完整验证码:
String message = "Die Strahlengriffelgewächse stammen ... ...
System.out.println("message");
System.out.println (message);
byte[] pack = Fbs.packExce(message);
System.out.println ("pack");
System.out.println (pack);
System.out.println ("packlenght:" + pack.length);
String toString = Base64.getEncoder().encodeToString(pack);
System.out.println ("toString");
System.out.println (toString);
byte[] toBytes = Base64.getDecoder().decode(toString);
System.out.println ("toBytes");
System.out.println (toBytes);
System.out.println ("toByteslength:" +toBytes.length);
String toBytesExtraction = extractExce(toBytes);
System.out.println ("toBytesExtraction");
System.out.println (toBytesExtraction);
String extraction = extractExce(pack);
System.out.println ("extraction");
System.out.println (extraction);
public static byte[] packExce(String text){
FlatBufferBuilder builder = new FlatBufferBuilder(0);
int textOffset = builder.createString(text);
Exce.startExce(builder);
Exce.addText(builder, textOffset);
int exce = Exce.endExce(builder);
Bucket.startBucket(builder);
Bucket.addContentType(builder, Post.Exce);
Bucket.addContent(builder, exce);
int buck = Bucket.endBucket(builder);
builder.finish(buck);
return builder.sizedByteArray();
//ByteBuffer buf = builder.dataBuffer();
//return buf;
//return Base64.getMimeEncoder().encodeToString(buf.array());
}
private String extractExce(byte[] bucket ){
String message = null;
ByteBuffer buf = ByteBuffer.wrap(bucket);
Bucket cont = Bucket.getRootAsBucket(buf);
System.out.println (cont.contentType());
if (cont.contentType() == Post.Exce){
message = ((Exce)cont.content(new Exce())).text();
}
return message;
}
这似乎对我有用:
...
pack
[B@5680a178
packlenght:2020
...
toBytes
[B@5fdef03a
toByteslength:2020
'''
----------------------
...
pack
[B@5680a178
packlenght:1872
...
toBytes
[B@5fdef03a
toByteslength:1872
...
并且分别从"toBytes"和"pack"中提取,忠实地还原了原来的"message"
String toBytesExtraction = extractExce(toBytes);
String extraction = extractExce(pack);
事实上,我没有提到的是我最初的实现是base64 mime。当时我的起点是 ByteBuffer(我现在是 byte[])。
如果您感兴趣,以下是我的代码片段。
编码器
...
ByteBuffer buf = builder.dataBuffer();
return Base64.getMimeEncoder().encodeToString(buf.array());
解码器
ByteBuffer buf = ByteBuffer.wrap(Base64.getMimeDecoder().decode(bucket));
我的猜测是问题可能来自 base64.mime。
因为我定位问题的第一步是去掉base64.mime,直接使用ByteBuffer。这是成功的...
嗯,我有点跑题了。
回到正题,关于字节数组在"new String(byte[]) and "String.getBytes()转换前后的“2字节变化”我还是一头雾水”...
干杯