![](/img/trans.png)
[英]In Java, how to convert correctly byte[] to String to byte[] again?
[英]byte[] to String to byte[] again
這是我想要做的。 我有一個字節[],需要用鍵(例如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] <<
我究竟做錯了什么? 有什么更好的解決方案嗎?
Arrays.toString()
不會將字節數組轉換為String。 出於調試目的,它提供了字節數組的String表示形式,就像List<Byte>.toString()
那樣。
Base64.encode()
應該將字節數組轉換為String。 並且Base64.decode()
應該將base64字符串轉換為相應的字節數組。 我見過的所有Base64庫都內置了這種方法。 您的也可能有一個。 如果不是,Base64包含ASCII字符,則可以簡單地使用
String storeStr = new String(base64Array, "ASCII");
和
byte[] bytes = storeStr.getBytes("ASCII");
我不知道您使用的是哪種base64編碼器,但是使用base64編碼字節數組的結果應該已經是String
...,同樣,當您解碼時,它應該將String
轉換為byte[]
。 不幸的是,某些base64 API在這方面設計得並不好-
我建議您看一下這個公共域庫 ,它具有更明智的API:
byte[] binary = ...;
String encoded = Base64.encodeBytes(binary);
// Send encoded to Redis...
byte[] decoded = Base64.decode(encoded);
您可以使用構造函數從byte []創建字符串:
//assuming you have a byte[] bytes
String string = new String(bytes);
然后寫回:
byte[] bytes = string.getBytes();
請記住,以64為基數是因為它的基數為64(可能為64)。 這意味着每個字符為2 ^ 6或6位。 Redis支持二進制安全字符串 ,因此它甚至可以接受非打印字符。 沒有理由將自己限制為64個漂亮的可打印Web安全字符(為什么人們使用B64)。
另一個問題是ASCII是0-127
,但是字節是-128 to 127
,所以我們不能直接映射,我們損失了一半的范圍(2 ^ 8 vs 2 ^ 7)。 如果我們使用UTF-8,則會得到所有這些位,即2 ^ 8或基數256。結果是我們可以將一個字節填充為1.25個B64字符,或單個UTF-8字符。 因此,UTF-8編碼將使用〜75%的空間作為B64編碼數據。 下面,由於B64使用了所有額外的填充=
字符,因此我們得到了更好的結果。
示例,編碼19個字節:
B64字符串: 28個字符
UTF8字符串: 19個字符(節省32%!)
// 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==
請記住,由於Redis在內存中,並且內存非常寶貴,因此您可能希望在應用開始填充二進制數據后將其轉換為UTF-8編碼,以節省一些空間。 缺點是它不像B64那樣易於人讀。
使用這2個函數進行轉換並轉換回
Convert.ToBase64String(en)
Convert.FromBase64String(input)
它橋接字節和字符串之間的鏈接。 並且確保沒有數據增加或丟失。 這是一個特殊的字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.