W Javie, jeśli mam ciąg x, jak mogę obliczyć liczbę bajtów w tym ciągu?
W Javie, jeśli mam ciąg x, jak mogę obliczyć liczbę bajtów w tym ciągu?
Odpowiedzi:
Łańcuch to lista znaków (tj. Punktów kodowych). Liczba bajtów używanych do reprezentowania ciągu zależy całkowicie od kodowania używanego do przekształcenia go w bajty .
To powiedziawszy, możesz przekształcić ciąg w tablicę bajtów, a następnie spojrzeć na jej rozmiar w następujący sposób:
// The input string for this test
final String string = "Hello World";
// Check length, in characters
System.out.println(string.length()); // prints "11"
// Check encoded sizes
final byte[] utf8Bytes = string.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "11"
final byte[] utf16Bytes= string.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "24"
final byte[] utf32Bytes = string.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "44"
final byte[] isoBytes = string.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "11"
final byte[] winBytes = string.getBytes("CP1252");
System.out.println(winBytes.length); // prints "11"
Więc widzisz, nawet prosty łańcuch „ASCII” może mieć różną liczbę bajtów w swojej reprezentacji, w zależności od zastosowanego kodowania. Użyj dowolnego zestawu znaków, który Cię interesuje, jako argumentu getBytes(). I nie wpadnij w pułapkę zakładania, że UTF-8 reprezentuje każdy znak jako pojedynczy bajt, ponieważ to też nie jest prawdą:
final String interesting = "\uF93D\uF936\uF949\uF942"; // Chinese ideograms
// Check length, in characters
System.out.println(interesting.length()); // prints "4"
// Check encoded sizes
final byte[] utf8Bytes = interesting.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "12"
final byte[] utf16Bytes= interesting.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "10"
final byte[] utf32Bytes = interesting.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "16"
final byte[] isoBytes = interesting.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "4" (probably encoded "????")
final byte[] winBytes = interesting.getBytes("CP1252");
System.out.println(winBytes.length); // prints "4" (probably encoded "????")
(Zwróć uwagę, że jeśli nie podasz argumentu zestawu znaków, używany jest domyślny zestaw znaków platformy . Może to być przydatne w niektórych kontekstach, ale generalnie należy unikać zależności od wartości domyślnych i zawsze używać jawnego zestawu znaków podczas kodowania / dekodowanie jest wymagane.)
getBytes()go użyjesz , użyje domyślnego kodowania znaków twojego systemu.
Jeśli korzystasz z odwołań 64-bitowych:
sizeof(string) =
8 + // object header used by the VM
8 + // 64-bit reference to char array (value)
8 + string.length() * 2 + // character array itself (object header + 16-bit chars)
4 + // offset integer
4 + // count integer
4 + // cached hash code
Innymi słowy:
sizeof(string) = 36 + string.length() * 2
Na 32-bitowej maszynie wirtualnej lub 64-bitowej maszynie wirtualnej ze skompresowanymi obiektami OOP (-XX: + UseCompressedOops) odwołania mają 4 bajty. Tak więc suma wyniosłaby:
sizeof(string) = 32 + string.length() * 2
Nie uwzględnia to odniesień do obiektu ciągu.
sizeofpowinna być wielokrotnością liczby 8.
Pedantyczna odpowiedź (choć niekoniecznie najbardziej użyteczna, w zależności od tego, co chcesz zrobić z wynikiem) to:
string.length() * 2
Ciągi Java są fizycznie przechowywane w UTF-16BEkodowaniu, które wykorzystuje 2 bajty na jednostkę kodu i String.length()mierzy długość w jednostkach kodu UTF-16, więc jest to równoważne z:
final byte[] utf16Bytes= string.getBytes("UTF-16BE");
System.out.println(utf16Bytes.length);
A to powie ci rozmiar wewnętrznej chartablicy w bajtach .
Uwaga: "UTF-16"da inny wynik niż "UTF-16BE"poprzednie kodowanie wstawi BOM , dodając 2 bajty do długości tablicy.
Zgodnie z Jak konwertować ciągi do iz tablic bajtów UTF8 w Javie :
String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);
s.getBytes(Charset.forName("UTF-8")).
StringPrzykład przydziela się określoną liczbę bajtów w pamięci. Może patrzysz na coś takiego, sizeof("Hello World")co zwróciłoby liczbę bajtów przydzielonych przez samą strukturę danych?
W Javie zwykle nie jest potrzebna sizeoffunkcja, ponieważ nigdy nie przydzielamy pamięci do przechowywania struktury danych. Możemy rzucić okiem na String.javaplik, aby uzyskać przybliżone oszacowanie, i widzimy trochę `` int '', kilka odniesień i plik char[]. Specyfikacja języka Java określa, że charzakres a wynosi od 0 do 65535, więc dwa bajty wystarczają, aby przechowywać w pamięci pojedynczy znak. Ale JVM nie musi przechowywać jednego znaku w 2 bajtach, musi tylko zagwarantować, że implementacja charmoże przechowywać wartości z zakresu definicji.
Więc sizeofnaprawdę nie ma to żadnego sensu w Javie. Ale zakładając, że mamy duży ciąg i jeden charprzydziela dwa bajty, wówczas ślad pamięci Stringobiektu jest co najmniej 2 * str.length()w bajtach.
Istnieje metoda o nazwie getBytes () . Używaj rozważnie .