Wie Anzahl String bytes korrekt?

Einer mit speziellen chars wie ç nimmt zwei bytes Größe in jedem speziellen char, aber String-length-Methode oder die Länge der es mit der byte-array zurückgegeben, von getBytes-Methode nicht zurück Besondere chars gezählt, die als zwei bytes.

Wie kann ich richtig zählen Sie die Anzahl der bytes in einem String?

Beispiel:

Das Wort endereço sollte mich zurückbringen Länge 9 statt 8.

  • Wenn ich System.out.println("endereço".getBytes().length); es gibt „9“.
  • welche version von Java? In Java-7 ich bin immer acht.
  • getBytes() nutzt die Plattform, Standard-Codierung, das kann schon sein UTF-8. Siehe: Platform die Standard-Zeichenkodierung auf verschiedenen Plattformen?
  • Ich bin mit Java 8. Ich nehme an, „utf-8“ ist ein Standard-Kodierung für jede version von Java, es sei denn, dieses Verhalten wird außer Kraft gesetzt, explizit.
  • Definieren von speziellen Zeichen. Was macht Sie denken, es dauert zwei Byte der Größe? Wo? Meinst du in der char[] sichern die String? Das Wort endereço sollte mich zurückbringen Länge 9 statt 8. Warum? Warum nicht 32?
  • UTF-8 ist nicht die Standard-Kodierung für jede version von Java. Die Standard-Kodierung ist im Allgemeinen definieren das Betriebssystem, und ist in der Regel UTF-8 auf Linux, aber nur selten unter WIndows.
  • Die Länge hängt stark von der Codierung, z.B. für endereço es ist ISO-8859-1: 8, UTF-8: 9, EUC-JP: 10, UTF-16BE: 16, UTF-32: 32
  • Ja, du hast Recht. Ich sehe “ – Datei.encoding“ – Eigenschaft mit dem Wert „UTF-8“, auch wenn ich nicht angeben. Explizite fallback für „UTF-8“ existiert nur in den code von java.nio.charset.Charset Klasse.
  • Ich war nicht immer die richtige Länge, da mein Standard-Kodierung ist ISO-8859-1.
  • Wieder definieren die Länge. Die String#length() Methode hat eine sehr spezifische definition.
  • Welche definition ist es exactally?
  • Alle Java Strings die Verwendung von zwei-byte-Zeichen intern.



One Reply
  1. 10

    Das Wort endereço sollte mich zurückbringen Länge 9 statt 8.

    Wenn Sie erwarten, haben eine Größe von 9 Byte für die "endereço" String hat die Länge 8 Zeichen : 7 ASCII Zeichen und 1 nicht ASCII Charakter, nehme ich an, das Sie verwenden möchten UTF-8 charset verwendet 1 byte für die Zeichen enthalten, die in der ASCII-Tabelle und mehr für die anderen.

    aber die String-length-Methode oder die Länge der es mit der byte –
    zurückgegebene array aus der getBytes-Methode nicht zurück special chars
    zählt das als zwei bytes.


    String length() Methode keine Antwort auf die Frage : , wie viele bytes verwendet werden ? Aber Antwort auf : „, wie viele „UTF-16-code-units“ oder einfach chars enthalten?

    String length() Javadoc :

    Gibt die Länge dieser Zeichenfolge. Die Länge ist gleich der Anzahl
    der Unicode-code-Einheiten, die in der Zeichenfolge.


    Den byte[] getBytes() – Methode ohne argument wird der String in ein byte-array. Sie konnte die length – Eigenschaft des zurückgegebenen Arrays zu wissen, wie viele bytes verwendet werden, von den kodierten String, aber das Ergebnis wird davon abhängen, der Zeichensatz verwendet, bei der Codierung.
    Aber die byte[] getBytes() Methode nicht zulassen, um anzugeben, charset : er nutzt die Plattform ist die Standard-Zeichenkodierung.

    Also, mit kann es nicht geben, das erwartete Ergebnis, wenn das zugrunde liegende Betriebssystem standardmäßig verwendet einen Zeichensatz, der nicht die eine, die Sie verwenden möchten, um die Kodierung des Strings in bytes.

    Nach Angaben der Plattform, wo die Anwendung bereitgestellt wird, die Weise, die die Zeichenfolge codiert sind, in bytes ändern kann. Das kann nicht wünschenswert sein.

    Endlich, wenn der String nicht kodiert werden kann, in der default-charset, ist das Verhalten nicht spezifiziert.

    So, sollte diese Methode verwendet werden, mit sehr Vorsicht oder gar nicht genutzt.

    byte[] getBytes() Javadoc :

    Kodiert, diesen String in eine Sequenz von bytes, die über die Plattform s
    Standard-Zeichensatz, speichern das Ergebnis in ein byte-array.

    Das Verhalten dieser Methode, wenn Sie diese Zeichenfolge nicht kodiert werden kann, in der
    default charset ist nicht spezifiziert. Die java.nio.charset.CharsetEncoder
    Klasse sollte verwendet werden, wenn mehr Kontrolle über den Erstellungsprozess ist
    erforderlich.

    In Ihrem String Beispiel "endereço", wenn getBytes() gibt ein array mit einer Größe von 8 und nicht 9, es bedeutet, dass Ihr Betriebssystem nicht standardmäßig verwendet werden UTF-8 aber einen Zeichensatz mit 1-byte fixed-width-Zeichen wie ISO 8859-1 und seine abgeleiteten Zeichensätze wie windows-1252 für Windows OS basieren.

    Wissen, die Standard-Zeichensatz der aktuellen Java virtual machine, wo die Anwendung ausgeführt wird, können Sie dieses utility verwenden Methode : Charset defaultCharset = Charset.defaultCharset().


    Lösung

    byte[] getBytes() Methode kommt mit zwei anderen sehr nützlich überlastungen :

    • byte[] java.lang.String.getBytes(String charsetName) throws UnsupportedEncodingException

    • byte[] java.lang.String.getBytes(Charset charset)

    Im Gegensatz zu den getBytes() – Methode ohne argument, diese Methoden lassen sich angeben, um die Zeichenkodierung zu verwenden, während der byte-Codierung.

    byte[] java.lang.String.getBytes(String charsetName) throws UnsupportedEncodingException Javadoc :

    Kodiert, diesen String in eine Byte-Sequenz mit dem „charset“,
    speichern das Ergebnis in ein byte-array.

    Das Verhalten dieser Methode, wenn Sie diese Zeichenfolge nicht kodiert werden kann, in der
    gegebenen Zeichensatz nicht angegeben ist. Die java.nio.charset.CharsetEncoder
    Klasse sollte verwendet werden, wenn mehr Kontrolle über den Erstellungsprozess ist
    erforderlich.

    byte[] java.lang.String.getBytes(Charset charset) Javadoc :

    Kodiert, diesen String in eine Byte-Sequenz mit dem angegebenen Zeichensatz
    speichern das Ergebnis in ein byte-array.

    Diese Methode ersetzt immer fehlerhafte-Eingang und unmappable-Charakter
    Sequenzen mit dieser Zeichensatz ist der Standard-Ersatz-byte-array. Die
    java.nio.charset.CharsetEncoder Klasse sollte verwendet werden, wenn mehr Kontrolle
    über die encoding-Prozess ist erforderlich.

    Sie können eine oder die andere (zwar gibt es einige Feinheiten zwischen Ihnen) zum Kodieren der Zeichenkette in ein byte-array mit UTF-8 oder andere charset und so bekommen Sie Ihre Größe für dieses spezielle charset .

    Beispielsweise um eine UTF-8 – encoding byte-array mit getBytes(String charsetName) können Sie tun :

    String yourString = "endereço";
    byte[] bytes = yourString.getBytes("UTF-8");
    int sizeInBytes = bytes.length;

    Und Sie erhalten eine Länge von 9 Byte, wie Sie möchten.

    Hier ist ein umfassender Beispiel mit Standard-Codierung angezeigt, byte-Codierung mit Standard-charset-Plattform UTF-8 und UTF-16 :

    public static void main(String[] args) throws UnsupportedEncodingException {
    
        //default charset
        Charset defaultCharset = Charset.defaultCharset();
        System.out.println("default charset = " + defaultCharset);
    
        //String sample
        String yourString = "endereço";
    
        // getBytes() with default platform encoding
        System.out.println("getBytes() with default charset, size = " + yourString.getBytes().length + System.lineSeparator());
    
        //getBytes() with specific charset UTF-8
        System.out.println("getBytes(\"UTF-8\"), size = " + yourString.getBytes("UTF-8").length);       
        System.out.println("getBytes(StandardCharsets.UTF_8), size = " + yourString.getBytes(StandardCharsets.UTF_8).length + System.lineSeparator());
    
        //getBytes() with specific charset UTF-16      
        System.out.println("getBytes(\"UTF-16\"), size = " + yourString.getBytes("UTF-16").length);     
        System.out.println("getBytes(StandardCharsets.UTF_16), size = " + yourString.getBytes(StandardCharsets.UTF_16).length);
    }

    Ausgabe auf meinem Rechner ist Windows-OS-basierten:

    default charset = windows-1252

    getBytes() mit default-Zeichensatz, Größe = 8

    getBytes(„UTF-8“), size = 9

    getBytes(StandardCharsets.UTF_8), Größe = 9

    getBytes(„UTF-16“), Größe = 18

    getBytes(StandardCharsets.UTF_16), Größe = 18

    • „String-length () – Methode keine Antwort auf die Frage : wie viele bytes werden verwendet ? Aber Antwort auf : „wieviele Zeichen sind enthalten?““ Nein, es gibt die Anzahl der UTF-16 code-Einheiten, die in der Zeichenfolge. Es können mehrere code-Einheiten pro code zeigen und es können mehrere code-Punkte pro „grapheme cluster“ (was die meisten Benutzer betrachten, ein Zeichen).
    • plugwash Technisch gesehen, ja, du hast Recht. Ich würde zu sehr vergröbert, denke ich. Ich hätte mehr spezifisch : „wie viele char enthalten sind?“ Ich aktualisiert. Vielen Dank für diese relevant Bemerkung 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.