Chciałbym traktować to jako problem serializacji i tylko realizowane w następujący sposób (kompletny i działa kod Java):
import java.nio.ByteBuffer;
import java.util.ArrayList;
public class Serialization {
public static byte[] serialize(String[] strs) {
ArrayList<Byte> byteList = new ArrayList<Byte>();
for (String str: strs) {
int len = str.getBytes().length;
ByteBuffer bb = ByteBuffer.allocate(4);
bb.putInt(len);
byte[] lenArray = bb.array();
for (byte b: lenArray) {
byteList.add(b);
}
byte[] strArray = str.getBytes();
for (byte b: strArray) {
byteList.add(b);
}
}
byte[] result = new byte[byteList.size()];
for (int i=0; i<byteList.size(); i++) {
result[i] = byteList.get(i);
}
return result;
}
public static String[] unserialize(byte[] bytes) {
ArrayList<String> strList = new ArrayList<String>();
for (int i=0; i< bytes.length;) {
byte[] lenArray = new byte[4];
for (int j=i; j<i+4; j++) {
lenArray[j-i] = bytes[j];
}
ByteBuffer wrapped = ByteBuffer.wrap(lenArray);
int len = wrapped.getInt();
byte[] strArray = new byte[len];
for (int k=i+4; k<i+4+len; k++) {
strArray[k-i-4] = bytes[k];
}
strList.add(new String(strArray));
i += 4+len;
}
return strList.toArray(new String[strList.size()]);
}
public static void main(String[] args) {
String[] input = {"This is","a serialization problem;","string concatenation will do as well","in some cases."};
byte[] byteArray = serialize(input);
String[] output = unserialize(byteArray);
for (String str: output) {
System.out.println(str);
}
}
}
Chodzi o to, że w otrzymanej tablicy bajtów przechowujemy długość pierwszego ciągu (co jest zawsze 4 bajty jeśli używamy typ int
), a następnie bajty pierwszego ciągu znaków (którego długość można odczytać później z poprzednich 4 bajtów), a następnie długość drugiego ciągu znaków i bajty drugiego łańcucha i tak dalej. W ten sposób tablica łańcuchów może zostać łatwo odzyskana z wynikowej tablicy bajtów, co zostało przedstawione w powyższym kodzie. I to podejście do serializacji może poradzić sobie z każdą sytuacją.
I kod może być znacznie prostsze, jeśli robimy założenie do tablicy ciąg wejściowy:
public class Concatenation {
public static byte[] concatenate(String[] strs) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<strs.length; i++) {
sb.append(strs[i]);
if (i != strs.length-1) {
sb.append("*.*"); //concatenate by this splitter
}
}
return sb.toString().getBytes();
}
public static String[] split(byte[] bytes) {
String entire = new String(bytes);
return entire.split("\\*\\.\\*");
}
public static void main(String[] args) {
String[] input = {"This is","a serialization problem;","string concatenation will do as well","in some cases."};
byte[] byteArray = concatenate(input);
String[] output = split(byteArray);
for (String str: output) {
System.out.println(str);
}
}
}
Założenie jest takie, że *.*
nie istnieje w dowolny ciąg z tablicy wejściowej. Innymi słowy, jeśli wiesz wcześniej, że specjalna sekwencja symboli nie pojawi się w żadnym ciągu tablicy wejściowej, możesz użyć tej sekwencji jako splittera.
Można iterować dla każdego ciągu i dołączać do ostatniej tablicy bajtów. Przykład śledzenia = "To jest przykład"; // Konwertuj ciąg na bajt [] używając funkcji .getBytes() bajt [] bytes = example.getBytes(); // Konwertuj bajt [] na String, używając nowego ciągu znaków (byte []) String s = new String (bytes); –
Widziałeś to pytanie? http://stackoverflow.com/questions/1536054/how-to-convert-byte-array-to-string-and-vice-versa –
Ali B - Myślę, że pytanie, które łączysz, odpowiada na nieco inne pytanie - szczególnie, gdy zobacz zaakceptowaną odpowiedź, która słusznie wskazuje, że "jeśli naprawdę chcesz przechowywać dane binarne w typie String, powinieneś używać kodowania Base64. – Floris