能否将byte[]
(字节数组)放入JSON
中?
如果可以,在Java中我该如何做?然后读取该JSON并将该字段再次转换为byte[]
?
能否将byte[]
(字节数组)放入JSON
中?
如果可以,在Java中我该如何做?然后读取该JSON并将该字段再次转换为byte[]
?
这是base64编码字节数组的良好示例。当您添加Unicode字符以发送像PDF文档之类的内容时,情况会变得更加复杂。编码字节数组后,编码后的字符串可用作JSON属性值。
Apache Commons提供了很好的实用工具:
byte[] bytes = getByteArr();
String base64String = Base64.encodeBase64String(bytes);
byte[] backToBytes = Base64.decodeBase64(base64String);
https://developer.mozilla.org/zh-CN/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
Java 服务器端示例:
public String getUnsecureContentBase64(String url)
throws ClientProtocolException, IOException {
//getUnsecureContent will generate some byte[]
byte[] result = getUnsecureContent(url);
// use apache org.apache.commons.codec.binary.Base64
// if you're sending back as a http request result you may have to
// org.apache.commons.httpclient.util.URIUtil.encodeQuery
return Base64.encodeBase64String(result);
}
JavaScript 解码:
//decode URL encoding if encoded before returning result
var uriEncodedString = decodeURIComponent(response);
var byteArr = base64DecToArr(uriEncodedString);
//from mozilla
function b64ToUint6 (nChr) {
return nChr > 64 && nChr < 91 ?
nChr - 65
: nChr > 96 && nChr < 123 ?
nChr - 71
: nChr > 47 && nChr < 58 ?
nChr + 4
: nChr === 43 ?
62
: nChr === 47 ?
63
:
0;
}
function base64DecToArr (sBase64, nBlocksSize) {
var
sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);
for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3;
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
}
nUint24 = 0;
}
}
return taBytes;
}
error: cannot find symbol method encodeBase64String(byte[])
和 error: incompatible types: String cannot be converted to byte[]
。你有什么线索吗? - Yusril Maulidan RajigetUnsecureContent
方法和 JavaScript 也不相关。(感觉问题后来被编辑了,即使没有标记,这种情况可能吗?如果是这样,我很抱歉。) - EndlosSchleife在json中发送二进制数据的典型方法是进行base64编码。
Java提供不同的方法来对byte[]
进行Base64编码和解码,其中之一是DatatypeConverter
。
非常简单。
byte[] originalBytes = new byte[] { 1, 2, 3, 4, 5};
String base64Encoded = DatatypeConverter.printBase64Binary(originalBytes);
byte[] base64Decoded = DatatypeConverter.parseBase64Binary(base64Encoded);
您将需要根据您使用的JSON解析器/生成器库进行此转换。
根据@Qwertie的建议,但更加懒惰的方法是,你可以假装每个字节都是ISO-8859-1字符。对于未经训练的人来说,ISO-8859-1是一种单字节编码,与Unicode的前256个代码点匹配。
因此,@Ash的答案实际上可以通过使用字符集来修复:
byte[] args2 = getByteArry();
String byteStr = new String(args2, Charset.forName("ISO-8859-1"));
这种编码与BAIS具有相同的可读性,但优势在于处理速度比BAIS或base64都要快,因为需要更少的分支。看起来JSON解析器似乎做了更多的工作,但这没关系,因为通过转义或UTF-8处理非ASCII字符是JSON解析器的一部分。它可能更适合某些格式,如具有配置文件的MessagePack。
然而,空间方面通常会损失一些。使用UTF-8每个非ASCII字节将占用2个字节,而BAIS每运行3n+r个这样的字节就使用(2+4n+r?(r+1):0)个字节(其中r是余数)。在UTF-16上会胜利,但谁会在JSON中使用呢?
(这种编码技巧适用于任何语言——8859-1得到了广泛支持。)
byte[]
,该值读作<Buffered Array: f0 ff ff ...>
,后者的长度表明大小增加了约300%,正如预期的那样。byte[]
。org.json将数组类型视为JSON数组,并序列化其元素的值。byte
被视为数字,因此生成的JSON只是一个数字的JSON数组。 - Savior{65,66,67}
变为简单的"ABC"
)。此外,BAIS通常比Base64给出更小的文件大小(但这并不保证)。import java.io.*;
import java.lang.*;
import java.util.*;
public class ByteArrayInString
{
// Encodes a byte array to a string with BAIS encoding, which
// preserves runs of ASCII characters unchanged.
//
// For simplicity, this method's base-64 encoding always encodes groups of
// three bytes if possible (as four characters). This decision may
// unfortunately cut off the beginning of some ASCII runs.
public static String convert(byte[] bytes) { return convert(bytes, true); }
public static String convert(byte[] bytes, boolean allowControlChars)
{
StringBuilder sb = new StringBuilder();
int i = 0;
int b;
while (i < bytes.length)
{
b = get(bytes,i++);
if (isAscii(b, allowControlChars))
sb.append((char)b);
else {
sb.append('\b');
// Do binary encoding in groups of 3 bytes
for (;; b = get(bytes,i++)) {
int accum = b;
if (i < bytes.length) {
b = get(bytes,i++);
accum = (accum << 8) | b;
if (i < bytes.length) {
b = get(bytes,i++);
accum = (accum << 8) | b;
sb.append(encodeBase64Digit(accum >> 18));
sb.append(encodeBase64Digit(accum >> 12));
sb.append(encodeBase64Digit(accum >> 6));
sb.append(encodeBase64Digit(accum));
if (i >= bytes.length)
break;
} else {
sb.append(encodeBase64Digit(accum >> 10));
sb.append(encodeBase64Digit(accum >> 4));
sb.append(encodeBase64Digit(accum << 2));
break;
}
} else {
sb.append(encodeBase64Digit(accum >> 2));
sb.append(encodeBase64Digit(accum << 4));
break;
}
if (isAscii(get(bytes,i), allowControlChars) &&
(i+1 >= bytes.length || isAscii(get(bytes,i), allowControlChars)) &&
(i+2 >= bytes.length || isAscii(get(bytes,i), allowControlChars))) {
sb.append('!'); // return to ASCII mode
break;
}
}
}
}
return sb.toString();
}
// Decodes a BAIS string back to a byte array.
public static byte[] convert(String s)
{
byte[] b;
try {
b = s.getBytes("UTF8");
} catch(UnsupportedEncodingException e) {
throw new RuntimeException(e.getMessage());
}
for (int i = 0; i < b.length - 1; ++i) {
if (b[i] == '\b') {
int iOut = i++;
for (;;) {
int cur;
if (i >= b.length || ((cur = get(b, i)) < 63 || cur > 126))
throw new RuntimeException("String cannot be interpreted as a BAIS array");
int digit = (cur - 64) & 63;
int zeros = 16 - 6; // number of 0 bits on right side of accum
int accum = digit << zeros;
while (++i < b.length)
{
if ((cur = get(b, i)) < 63 || cur > 126)
break;
digit = (cur - 64) & 63;
zeros -= 6;
accum |= digit << zeros;
if (zeros <= 8)
{
b[iOut++] = (byte)(accum >> 8);
accum <<= 8;
zeros += 8;
}
}
if ((accum & 0xFF00) != 0 || (i < b.length && b[i] != '!'))
throw new RuntimeException("String cannot be interpreted as BAIS array");
i++;
// Start taking bytes verbatim
while (i < b.length && b[i] != '\b')
b[iOut++] = b[i++];
if (i >= b.length)
return Arrays.copyOfRange(b, 0, iOut);
i++;
}
}
}
return b;
}
static int get(byte[] bytes, int i) { return ((int)bytes[i]) & 0xFF; }
public static int decodeBase64Digit(char digit)
{ return digit >= 63 && digit <= 126 ? (digit - 64) & 63 : -1; }
public static char encodeBase64Digit(int digit)
{ return (char)((digit + 1 & 63) + 63); }
static boolean isAscii(int b, boolean allowControlChars)
{ return b < 127 && (b >= 32 || (allowControlChars && b != '\b')); }
}
这样怎么样:
byte[] args2 = getByteArry();
String byteStr = new String(args2);