Czy to jest poprawne podejście do konwersji ByteBuffer na String w ten sposób,
String k = "abcd";
ByteBuffer b = ByteBuffer.wrap(k.getBytes());
String v = new String(b.array());
if(k.equals(v))
System.out.println("it worked");
else
System.out.println("did not work");
Pytam o to, że wygląda to na zbyt proste, podczas gdy inne podejścia, takie jak Java: Konwersja ciągu do iz ByteBuffera i powiązane problemy wyglądają na bardziej złożone.
java
string
serialization
bytearray
vikky.rk
źródło
źródło
Odpowiedzi:
EDYCJA (2018): Edytowana odpowiedź rodzeństwa autorstwa @xinyongCheng jest prostszym podejściem i powinna być akceptowaną odpowiedzią.
Twoje podejście byłoby rozsądne, gdybyś wiedział, że bajty znajdują się w domyślnym zestawie znaków platformy. W twoim przykładzie jest to prawda, ponieważ
k.getBytes()
zwraca bajty w domyślnym zestawie znaków platformy.Częściej będziesz chciał określić kodowanie. Jest jednak na to prostszy sposób niż pytanie, które łączysz. String API udostępnia metody, które konwertują między String a tablicą byte [] w określonym kodowaniu. Te metody sugerują użycie CharsetEncoder / CharsetDecoder „gdy wymagana jest większa kontrola nad procesem dekodowania [kodowania]”.
Aby uzyskać bajty z String w określonym kodowaniu, możesz użyć siostrzanej metody getBytes ():
Aby umieścić bajty z określonym kodowaniem w String, możesz użyć innego konstruktora String:
Zauważ, że
ByteBuffer.array()
jest to operacja opcjonalna. Jeśli zbudowałeś swój ByteBuffer z tablicą, możesz użyć tej tablicy bezpośrednio. W przeciwnym razie, jeśli chcesz być bezpieczny, użyj polecenia,ByteBuffer.get(byte[] dst, int offset, int length)
aby pobrać bajty z bufora do tablicy bajtów.źródło
ByteBuffer.get
funkcji dane wejściowe są ponownie tablicą bajtów, jak mogę to uzyskać? nie ma sensu powtarzać k.getbytes, prawda?ByteBuffer.get(byte[] dst, int offset, int length)
. Możesz zbudować z niego String za pomocą konstruktora String () `String (byte [] bytes, int offset, int length, Charset charset). Możesz użyć tych samych wartości przesunięcia i długości dla obu wywołań.k
jest String, a nie ByteBuffer.Jest prostsze podejście do dekodowania a
ByteBuffer
na aString
bez żadnych problemów, o którym wspomniał Andy Thomas.źródło
CharBuffer
decode()
zwraca toCharSequence
(lubięString
), więc możesz uniknąć dodatkowej kopii i użyć jej bezpośrednio.Spróbuj tego:
NB. nie możesz poprawnie przekonwertować tablicy bajtów na String bez znajomości jej kodowania.
mam nadzieję, że to pomoże
źródło
.array()
może zgłosić wyjątek..array()
metodę.array()
, musisz również użyć,arrayOffset()
aby rozpocząć od właściwej pozycji w tablicy! Jest to subtelna pułapka, ponieważ zwykle arrayOffset () ma wartość 0; ale w tych rzadkich przypadkach, w których tak nie jest, pojawią się trudne do znalezienia błędy, jeśli nie weźmiesz ich pod uwagę.Chciałem tylko podkreślić, że nie jest bezpiecznie zakładać, że ByteBuffer.array () będzie zawsze działać.
Zazwyczaj wartość buffer.hasArray () zawsze będzie miała wartość true lub false, w zależności od przypadku użycia. W praktyce, chyba że naprawdę chcesz, aby działało w żadnych okolicznościach, możesz bezpiecznie zoptymalizować gałąź, której nie potrzebujesz. Ale pozostałe odpowiedzi mogą nie działać z ByteBuffer, który został utworzony przez ByteBuffer.allocateDirect ().
źródło
ByteBuffer.wrap(bytes, offset, size)
fabrykę.array()
, zwróci całąbytes
tablicę. Lepiej użyj formy sugerowanej przez xinyong Chengarray()
, musisz również użyć,arrayOffset()
aby rozpocząć od właściwej pozycji w tablicy! Jest to subtelna pułapka, ponieważ zwykle arrayOffset () ma wartość 0; ale w tych rzadkich przypadkach, w których tak nie jest, pojawią się trudne do znalezienia błędy, jeśli nie weźmiesz ich pod uwagę.Odpowiedzi odnoszące się do prostego wywołania
array()
nie są do końca poprawne: gdy bufor został częściowo zużyty lub odnosi się do części tablicy (możnaByteBuffer.wrap
tablicę z podanym przesunięciem, niekoniecznie od początku), musimy się liczyć to w naszych obliczeniach. To jest ogólne rozwiązanie, które działa dla buforów we wszystkich przypadkach (nie obejmuje kodowania):Jeśli chodzi o obawy związane z kodowaniem, zobacz odpowiedź Andy'ego Thomasa.
źródło
źródłem tego pytania jest jak zdekodować bajty do łańcucha?
można to zrobić za pomocą zestawu znaków JAVA NIO:
public final CharBuffer decode(ByteBuffer bb)
źródło
Zauważ (pomijając problem z kodowaniem), że niektóre bardziej skomplikowane powiązane kody powodują problemy z uzyskaniem „aktywnej” części danego ByteBuffer (na przykład przez użycie pozycji i limitu), zamiast po prostu zakodować wszystkie bajty w całej tablicy bazowej (jak wiele przykładów w tych odpowiedziach).
źródło
Przekonwertuj String na ByteBuffer, a następnie z ByteBuffer z powrotem na String używając Java:
Który najpierw drukuje wydrukowany czysty ciąg, a następnie ByteBuffer rzutowany na array ():
Było to również pomocne dla mnie, zredukowanie ciągu do pierwotnych bajtów może pomóc w sprawdzeniu, co się dzieje:
Wyświetla ciąg znaków interpretowany jako UTF-8, a następnie ponownie jako ISO-8859-1:
źródło
źródło