1

这是我想要做的。我有一个 byte[] 需要用键(比如 key1)存储在 Redis 中,Redis 会将其存储为字符串。我需要在通过 key1 检索值时重建 byte[]

    //here is a byte array
    byte[] bArr = new byte[] {83, 71, 86, 115, 98, 71, 56, 103, 84, 88, 73, 117, 73, 69, 104, 118, 100, 121, 66, 107, 98, 121, 66, 53, 98, 51, 85, 103, 90, 71, 56, 47}; //"Hello World"; 

    // I will have to store this as a byte string into redis
    //Base64 encoding
    bArr = Base64.encodeBase64(bArr);
    String storeStr = Arrays.toString(bArr) ;
    // storeStr is what gets stored in redis
    System.out.println("storeStr>>" + storeStr+ "<<");
    // I will get this string back from redis
    // now trying to reconstruct the byte[]
    byte[] aArr = Base64.decodeBase64(storeStr); 
    System.out.println("readStr>>" + Arrays.toString(aArr)+ "<<");  

但我得到以下输出:

storeStr>>[85, 48, 100, 87, 99, 50, 74, 72, 79, 71, 100, 85, 87, 69, 108, 49, 83, 85, 86, 111, 100, 109, 82, 53、81、109、116、105、101、85、73、49、89、106、78、86、90、49、112、72、79、67、56、61]<< readStr>>[-13 , -98, 60, -41, 77, 60, -17, -33, 121, -45, -66, 59, -37, -65, 123, -41, 93, 52, -13, -97, 59、-21、-35、116、-13、-113、124、-33、-50、124、-21、93、117、-41、77、53、-45、-33、54、-25 , 127, 53, -41, 79, 117, -41, -83, 116, -25, 93, 53, -13, -98, -9, -29, -33, 61, -41, 78, - 69、-13、-50、-67、-45、-113、117、-41、110、-10、-17、-34、-69、-25、-82、-75]<<

我究竟做错了什么?有没有更好的解决方案?

4

5 回答 5

6

Arrays.toString()不会将字节数组转换为字符串。它提供了一个字节数组的字符串表示,用于调试目的,就像List<Byte>.toString()这样做一样。

Base64.encode()应该将字节数组转换为字符串。并且Base64.decode()应该将 base64 字符串转换为相应的字节数组。我见过的所有 Base64 库都内置了这样的方法。你的可能也有一个。如果没有,Base64 包含 ASCII 字符,您可以简单地使用

String storeStr = new String(base64Array, "ASCII");

byte[] bytes = storeStr.getBytes("ASCII");
于 2013-02-28T22:22:46.840 回答
2

我不知道您使用的是什么 base64 编码器,但是使用 base64 对字节数组进行编码的结果应该已经是 a String... 同样,当您解码时,它应该将 a 转换String为 a byte[]。不幸的是,一些 base64 API 在这方面设计得不是很好——

我建议你看看这个公共领域库,它有一个更明智的 API:

byte[] binary = ...;
String encoded = Base64.encodeBytes(binary);

// Send encoded to Redis...

byte[] decoded = Base64.decode(encoded);
于 2013-02-28T22:19:55.573 回答
1

Remember, base 64 is called that because it has a radix of 64 (64 possible values). That means each character is 2^6, or 6 bits. Redis supports binary safe strings, so it can take even non-printing characters. There is no reason to limit ourselves to 64 pretty printing, websafe characters (why people use B64).

The other problem is ASCII is 0-127, but byte is -128 to 127, so we can't map directly, we lose half the range (2^8 vs 2^7). If we use UTF-8, we get all those bits, so 2^8 or radix 256. The result is we can stuff one byte into 1.25 B64 characters, or a single UTF-8 character. Thus, UTF-8 encoding will use ~75% of the space as the B64 encoded data. Below we get better than that because of all the extra padding = characters B64 uses.

Example, encoding 19 bytes:

B64 String: 28 characters

UTF8 String: 19 characters (32% savings!)

// setup
byte[] bytes = new byte[]{-10, 1, 3, 85, 48, 100, 87, 99, 050, 74, 79, 71, 100, 85, 87, -120, 108, -128, 30};

// full UTF-8 range
String outFullRange = new String(bytes, "UTF-8");
System.out.println(outFullRange); // prints �U0dWc(JOGdUW�l�

// just Base64
String outB64 = Base64.encode(bytes);
System.out.println(outB64);// 9gEDVTBkV2MoSk9HZFVXiGyAHg==

Remember, since Redis is in memory, and memory is precious, you might want to switch binary data to UTF-8 encoding once you app starts to fill up for some quick space savings. The downside is that it's not as human readable as B64.

于 2015-03-25T16:01:08.387 回答
1

您可以使用构造函数从 byte[] 创建字符串:

//assuming you have a byte[] bytes
String string = new String(bytes);

然后将其写回:

byte[] bytes = string.getBytes();
于 2013-02-28T22:49:02.777 回答
0

使用这2个函数进行转换和转换回

Convert.ToBase64String(en)

Convert.FromBase64String(input)

它桥接了字节和字符串之间的链接。并确保没有数据添加或丢失。这是一个特殊的字符串。

https://en.wikipedia.org/wiki/Base64

于 2016-05-31T05:27:23.173 回答