# Wo das encoding festlegen?



## MikeThomson (25. Feb 2009)

Hallo,

ich lese wie folgt Daten aus einem ByteStream ein:


```
String str = "";
byte ble = ReadIn.readByte();
if (! (ble <= 0)) {
	byte[] ada = new byte[ble * 16];
	ReadIn.read(ada, 0, ble * 16);

	int zero = 0;
	
        while ( (zero < ada.length) && (ada[zero] != 0)) {
		str += (char) ada[zero];
		zero++;
	}
```

Meine Frage ist. Wo spezifiziere ich das encoding? Der ByteStream sendet unter anderem auch Französische "Sonderzeichen" (é è) in einem anderen Encoding. Ich vermute utf-8.

Nur wo und wie spezifiziere ich das Encoding? 

```
str += [UTF8](char) ada[zero]; ????
```


----------



## Wildcard (25. Feb 2009)

Das str += wird extrem langsam. Solltest du auf StringBuffer umstellen.
Ein char kennt kein Encoding. Strings hingegen schon und Strings bieten spezielle Konstruktoren:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#String(byte[],%20java.lang.String)
Du könntest auch einen Reader verwenden um von dieser low-level Schiene wegzukommen und dort ein Encoding setzen.


----------



## MikeThomson (25. Feb 2009)

Danke für den Tip,

aber irgendwie komm ich noch nicht so zurecht.

Wenn ich den Konstruktor richtig verstehe:

```
String(byte[] bytes,
              String charsetName)
       throws UnsupportedEncodingException
```

könnte ich ein String str = new String(...bytes...,"UTF8"); machen. Nur wie packe ich dann weitere Chars drauf? Würde ein:


```
str = new String(0,"UTF8"); 
str += (char)ada[zero];
```

funktionieren?

Angenommen ich würde auf einen StringBuffer umsteigen. Ich finde hier http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StringBuffer.html keine Möglichkeit ein charset festzulegen?

Bin für jedes kleine Beispiel dankbar.


----------



## Wildcard (25. Feb 2009)

Ein String ist unveränderlich, du kannst also auch nichts anhängen, nur neue Strings erzeugen. Ein Buffer braucht kein Encoding, weil es im 'Speicher' keine verschiedenen Encodings gibt, nur noch Java. Die Encodings sind nur für die Schnittstellen nach aussen interessant, wenn etwas rausgeschrieben/eingelesen werden soll.
Wie gesagt, nimm doch einfach einen Reader. Da stellst du dein Encoding ein und liest aus dem Stream.


----------



## MikeThomson (26. Feb 2009)

Hallo Wildcard,

ein Reader darf ich leider nicht verwenden. Wie du schon sagtest ist ein StringBuffer sicherlich performanter.

Allerdings verstehe ich die Logik des Buffers nicht wenn ich kein charset angeben kann.

Angenommen ich mache:


```
StringBuffer sb = new StringBuffer();
sb.append("CHINESISCHE ZEICHEN");
System.out.println(sb.toString());
```

Woher weiß denn dann der Buffer um was für Zeichen es sich handelt? Bzw. genauer gefragt. Woher weiß der Buffer was er bei sb.toString() zu liefern hat? Auch hier gibt es ja kein Parameter charset.


----------



## HoaX (26. Feb 2009)

Ein String ist schon codiert, darum kann es dem StringBuffer egal sein.


----------



## Ebenius (26. Feb 2009)

Ich versuch's auch mal. In Java ist jedes _char_ ein Unicode-Zeichen. Es kann also jedes von Dir benötigte Zeichen aufnehmen. Ein String besteht aus _char_s und kann damit auch jedes Unicode-Zeichen aufnehmen. Selbiges trifft auf StringBuffer und StringBuilder zu. Alles Unicode.

Wie oben schon erwähnt: Zeichensatzkodierung und -Dekodierung brauchst Du nur dann, wenn _byte_s interpretiert werden um daraus _char_s zu machen.

Wenn Du chinesische, arabische, japanische, ... Zeichen im Quelltext stehen haben möchtest, dann muss der Compiler (javac) die _byte_s Deines Quelltexts interpretieren. Dazu benötigt der Compiler einen Zeichensatz. Wenn Du keinen angibst, nimmt er den in der Umgebung eingestellten Zeichensatz. Den Zeichensatz der Zur Interpretation des Quelltextes benutzt wird kann man so explizit angeben: 
	
	
	
	





```
javac -encoding latin1 ...
javac -encoding big5 ...
javac -encoding UTF-8 ...
...
```

Du kannst also -- analog zu Deinem obigen Beispiel -- einfach chinesische oder arabische Zeichen in einen StringBuffer tun: [HIGHLIGHT="Java"]StringBuffer sb = new StringBuffer();

// "Ich bin ein Chinese" in vereinfachtem chinesisch
sb.append("我是一个中国");

// "Ich bin ein Chinese" in traditionellem chinesisch
sb.append("我是一個中國");

// "Ich bin ein Araber" in arabisch
sb.append("انا عربي");[/HIGHLIGHT]... in Google Translate BETA übersetzt

Allerdings sollte man meiner Meinung nach solche Zeichenketten lieber nicht im Quelltext angeben, sondern die entsprechenden Unicode-Zeichen per Unicode eintragen. Das erspart einem das Problem, beim Kompilieren den Zeichensatz kennen zu müssen. In Java macht man das also so: [HIGHLIGHT="Java"]// Das Zeichen HORIZONTAL ELLIPSIS einfügen: …
sb.append("\u2026");[/HIGHLIGHT]

Erklärt's das ein bisschen?
Ebenius


----------

