2009-03-30 14 views
22

Muszę konwertować char w bajt lub tablicy bajtowej. W innych językach wiem, że char to tylko jeden bajt. Jednak patrząc na klasę znaków Java, jej minimalną wartością jest \ u0000, a jej maksymalna wartość to \ uFFFF. To sprawia, że ​​wygląda na to, że znak ma długość 2 bajtów.Reprezentowanie char jako bajt w Javie

Czy będę w stanie zapisać go jako bajt, czy też muszę go zapisać jako dwa bajty?

Zanim ktokolwiek zapyta, powiem, że próbuję to zrobić, ponieważ pracuję pod interfejsem, który oczekuje, że moje wyniki będą tablicą bajtów. Muszę więc przekonwertować mój znak na taki.

Proszę dać mi znać i pomóc mi zrozumieć.

Dzięki, JBU

Odpowiedz

34

Aby przekonwertować znaki na bajty, trzeba określić character encoding. Niektóre kodowania znaków używają jednego bajtu na znak, podczas gdy inne używają dwóch lub więcej bajtów. W rzeczywistości dla wielu języków istnieje zbyt wiele znaków do kodowania za pomocą jednego bajtu.

W języku Java najprostszym sposobem na konwersję ze znaków na bajty jest użycie metodyklasy . Jednak ta metoda spowoduje dyskretne zastąpienie znaków za pomocą & # xfffd; jeśli znaku nie można zmapować pod określonym kodowaniem. Jeśli potrzebujesz większej kontroli, możesz skonfigurować CharsetEncoder do obsługi tego przypadku z błędem lub użyć innego znaku zastępczego.

+1

używać UTF-8 i przechowywanie moje znaki jako jeden bajt być ok? Myślę, że tak, nawet jeśli ten ostatni fragment był znakiem bitowym. – jbu

+0

Powinieneś użyć kodowania znaków wymaganego przez interfejs, pod którym pracujesz. – erickson

+1

Dla kodowania pojedynczego bajtu używamy rodziny ISO-8859 –

0

char w java jest niepodpisaną 16-bitową wartością. Jeśli to, co masz zmieści się w 7 bitach, po prostu wykonaj rzutowanie na bajt (na przykład zmieści się ASCII).

Można również wypróbować interfejsy API java.nio.charset.

+0

Musi zmieścić się w 7 bitach do bezpiecznej pracy. – erickson

+0

Tak, nie chciałem uzyskać rozszerzonego ASCII ... ale zaktualizuję odpowiedź. – TofuBeer

4

Aby przedłużyć, co mówią inni, jeśli masz char że trzeba jako tablicy bajtów, to najpierw utworzyć ciąg zawierający ten char, a następnie dostać tablicę bajtów z String:

private byte[] charToBytes(final char x) { 
    String temp = new String(new char[] {x}); 
    try { 
    return temp.getBytes("ISO-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
    // Log a complaint 
    return null; 
    } 
} 

Oczywiście użyj odpowiedniego zestawu znaków. O wiele bardziej efektywne byłoby rozpoczęcie pracy z ciągami, zamiast pobierania znaku w danym momencie, konwersja na ciąg znaków, a następnie zamiana na tablicę bajtów.

8

Char jest rzeczywiście 16 bitów w Javie (i jest również jedynym niepodpisanym typem !!).

Jeśli jesteś pewien, że kodowanie twoich znaków jest ASCII, możesz je po prostu odrzucić na bajcie (ponieważ ASCII używa tylko 7 niższych bitów znaku).

Jeśli nie trzeba modyfikować znaków albo zrozumieć ich signification ciągu znaków, można po prostu przechowywać znaki na dwóch bajtach, jak:

char[] c = ...; 
byte[] b = new byte[c.length*2]; 
for(int i=0; i<c.length; i++) { 
    b[2*i] = (byte) (c[i]&0xFF00)>>8; 
    b[2*i+1] = (byte) (c[i]&0x00FF); 
} 

(może to być wskazane, aby zastąpić 2 * przez prawą zmianę, jeśli prędkość ma znaczenie).

Należy jednak zauważyć, że niektóre rzeczywiste (wyświetlane) znaki (lub dokładniej punkty kodu Unicode) są zapisywane na dwóch kolejnych znakach. Zatem przecięcie między dwoma znakami nie gwarantuje, że przecinasz rzeczywiste postacie.

Jeśli musisz dekodować/kodować lub w inny sposób manipulować tablicą znaków w sposób ciągły, powinieneś raczej spróbować rozszyfrować i zakodować tablicę znaków lub łańcuch używając java.io narzędzia, które zapewniają odpowiednią manipulację postaciami.

+0

Zamiast kodu pokazanego tutaj, określ "UTF-16" jako kodowanie znaków i użyj wbudowanych interfejsów API do kodowania. Mniej kodu, który można zaimplementować, przetestować i utrzymywać, i lepiej uchwycić zamiar czytelników kodu. – erickson

+0

A także dwa rzędy wielkości mniej w prędkości, z powodu kodowania/dekodowania, które mogą nie być potrzebne w tym przypadku. – Varkhan

+0

To jest tylko kodowanie, a jeśli jest wolniejsze (co wątpię), to nie jest współczynnik 100. Dlaczego według ciebie kodowanie UTF-16 robi coś znacznie innego niż twój kod? – erickson