# Japanischen Text aus Textdokument einlesen



## Ikaragua (15. Aug 2008)

Hallo.

Mein Ziel ist es eine Zeile, die Teile japanischer Schrift beinhaltet, korrekt auszulesen, doch meinem BufferedReader gelingt es aus mir unerklärlichen Gründen nicht und gibt nur Wirrnis aus.

Mittels welchen Wegs ist dieses zu bewerkstelligen?

Danke bereits hier.


----------



## Ark (15. Aug 2008)

Du musst die genaue Bezeichnung des Zeichensatzes kennen, den der Text verwendet, und z.B. einem InputStreamReader bei Konstruktion mitteilen. Der Zeichensatz könnte ein "spezieller" wie Shift_JIS sein, kann aber auch ein Unicode-Zeichensatz sein. Dass nur Wirrwarr herauskommt, liegt wahrscheinlich daran, dass der (Standard-)Zeichensatz nicht einmal im Ansatz zum zu verwendenen kompatibel ist.

Ark


----------



## Ikaragua (15. Aug 2008)

Mein Dokument ist mit der Unicode-Codierung versehen, doch wie soll ich meinem BufferedReader mitteilen, dass das Dokument jenen hat?


----------



## Wildcard (15. Aug 2008)

Unicode sollte kein Problem sein, aber wie stellst du fest, das nicht das richtige eingelesen wird?


----------



## Ikaragua (15. Aug 2008)

Das ist der Dokumentinhalt:


> 先生が新設に教えてくださるのでわたし日本語もかなりじょうずになりました。§Sensei=ga sinsetsu=ni osie.te kudasar.u=no=de watashi=no nihon.go=mo kanari zyoozu=ni nari.masi.ta.§Da mein Lehrer mir so netten Unterricht erteilt, ist auch mein Japanisch ziemlich gut geworden.


Und so gibt es mir System.out.println aus:


> ÿþHQuL0°e-Šk0YeH0f0O0`0U0‹0n0g0?0_0W0åe,gžŠ‚0K0j0Š0X0‡0F0Z0k0j0Š0~0W0_00



//Nachtrag:

```
public void datenEinlesen() {
        try {
            BufferedReader einlesenZaehlen = new BufferedReader(new FileReader("JS.txt"));
            String zaehlen;
            zeilenanzahl = 0;
            
            while ((zaehlen = einlesenZaehlen.readLine()) != null) {
                zeilenanzahl = zeilenanzahl + 1;
            }
            stringarray_Datei = new String [zeilenanzahl][3];
            einlesenZaehlen.close();
            
            BufferedReader einlesenZuweisen = new BufferedReader(new FileReader("JS.txt"));
            String zuweisen;
            int gegenwaertigeZeile = 0;
            while ((zuweisen = einlesenZuweisen.readLine()) != null) {
                stringarray_Zeile = zuweisen.split("§");
                System.out.println(stringarray_Zeile[0] + " " + stringarray_Zeile[1] + " " + stringarray_Zeile[2]);
                if (zeilenanzahl > gegenwaertigeZeile) {
                    stringarray_Datei[gegenwaertigeZeile][0] = stringarray_Zeile[0];
                    stringarray_Datei[gegenwaertigeZeile][1] = stringarray_Zeile[1];
                    stringarray_Datei[gegenwaertigeZeile][2] = stringarray_Zeile[2];
                }
                gegenwaertigeZeile = gegenwaertigeZeile + 1;
            }
            einlesenZuweisen.close();
        } catch (Exception ausnahme) {
            ausnahme.printStackTrace();
        }
    }
```


----------



## Ark (15. Aug 2008)

```
BufferedReader einlesenZaehlen = new BufferedReader(new InputStreamReader(new FileInputStream("JS.txt"), "UTF-16BE"));
```
So in der Art sollte das an allen relevanten Stellen aussehen, eventuell ist der Zeichensatz falsch gewählt (oder ich habe ihn falsch benannt).

Ark

(Hey, da kann jemand drei Zeichen aus meiner Signatur lesen. xD)


----------



## Wildcard (15. Aug 2008)

Welche Konsole gibt deinen Standardoutput wieder?
Die muss nämlich auch Japanisch unterstützen (ebenso wie der verwendete Font).


----------



## Ikaragua (15. Aug 2008)

Wildcard hat gesagt.:
			
		

> Welche Konsole gibt deinen Standardoutput wieder?
> Die muss nämlich auch Japanisch unterstützen (ebenso wie der verwendete Font).


Das ist allerdings möglich, dass die NetBeans "Konsole" kein Unicode unterstützt. Zudem ist in dem Quelltext noch ein ArrayIndexOutOfBoundsException, weshalb es wohl auch nicht auf dem GUI angezeigt wird.

//Nachtrag:
Die ArrayIndexOutOfBoundsException wird allen Anschein nach von den jap. Zeichen ausgelöst. Ein Versuch mit lateinischen Zeichen hat das bestätigt.

Leider funktioniert deine Lösung auch nicht, Ark.

//Zweiter Nachtrag:
Scheinbar zählt das JRE bei zwei echten Zeilen drei.


----------



## Ark (15. Aug 2008)

Ikaragua hat gesagt.:
			
		

> Das ist allerdings möglich, dass die NetBeans "Konsole" kein Unicode unterstützt. Zudem ist in dem Quelltext noch ein ArrayIndexOutOfBoundsException, weshalb es wohl auch nicht auf dem GUI angezeigt wird.


Dass das Problem bei NetBeans liegen sollte, halte ich für weniger wahrscheinlich. Zeige doch bitte den Stack-Trace-Auszug.



			
				Ikaragua hat gesagt.:
			
		

> Leider funktioniert deine Lösung auch nicht, Ark.


Woran genau scheint es denn zu scheitern bzw. was bewirkt mein Code?



			
				Ikaragua hat gesagt.:
			
		

> Scheinbar zählt das JRE bei zwei echten Zeilen drei.


Klingt nach einem Zeichensatzfehler.

Ark


----------



## Wildcard (15. Aug 2008)

1. Die Netbeans Konsole unterstützt sicherlich keine Japanischen Zeichen
2. Die JRE zählt keine Zeichen
3. Ein Unicode Character passt nicht immer in ein char.


----------



## Ikaragua (15. Aug 2008)

> Dass das Problem bei NetBeans liegen sollte, halte ich für weniger wahrscheinlich. Zeige doch bitte den Stack-Trace-Auszug.




```
java.lang.ArrayIndexOutOfBoundsException: 1
        at JLS.Komponenten.datenEinlesen(Komponenten.java:136)
        at JLS.Hauptklasse.main(Hauptklasse.java:7)
```
Diese Exception tritt nur dann auf, sollten sich jap. Zeichen in JS.txt befinden. 
Bei einem Dokumenteninhalt von


> s;s;s
> d;d;d


funktioniert alles wie es das soll.



> Woran genau scheint es denn zu scheitern bzw. was bewirkt mein Code?


Es gab schlichtweg keine merklichen Veränderungen. Lediglich die Wirrnis ändert sich mit geändertem Zeichensatz beim InputStreamReader.



> Klingt nach einem Zeichensatzfehler.


Ich glaube auch immer mehr, es liegt am JRE...


----------



## Wildcard (15. Aug 2008)

Da steht doch das die Exception bei dir kommt.
Ausserdem: siehe mein Posting weiter oben


----------



## Ikaragua (15. Aug 2008)

Es könnte auch sein, dass ich einen völlig falschen Ansatz habe. Könnte jemand etwas so geartetes programmieren, dass funktionierend jap. Zeichen liest und in einem GUI darstellt, welches ich dann auf meinem System ausprobiere?


----------



## Wildcard (15. Aug 2008)

Nimm einen BufferedReader und einen BufferedWriter.
Lies die Datei und schreib den String anschließend in eine andere Datei.
Wenn beide identisch sind hast du das richtige Encoding verwendet.


----------



## Ark (15. Aug 2008)

Wildcard hat gesagt.:
			
		

> 3. Ein Unicode Character passt nicht immer in ein char.


So weit ich das überblicke, scheinen alle verwendeten Zeichen Codes <=0xFFFF zu benötigen, es wird also reichen.

Ark

EDIT: Zu Wildcard's Vorschlag noch: Führe dann aber besser nach jedem Schreibvorgang ein flush() aus, damit wir dann keine leere Datei bewundern müssen, wenn der Fehler kommt. 

Ark


----------



## Ikaragua (15. Aug 2008)

Interessant... Es scheint, als können die Buffered-Routinen mit Unicode umgehen, selbst mit übergebenen FileReader, also ohne expliziter Zeichensatznennung.
Doch wo ist nun der Fehler?


----------



## Wildcard (15. Aug 2008)

Natürlich kann Java mit Unicode umgehen, sogar problemlos. Wenn du kein Encoding angibst wird normalerweise das der Plattform verwendet.


> Doch wo ist nun der Fehler?


Im code natürlich, wo sonst?


----------



## Ark (15. Aug 2008)

Dass das Lesen und Schreiben funktionieren, liegt ja auch ganz einfach daran, dass die Zeichensätze beim Lesen und Schreiben übereinstimmen. Du hättest genausogut auch byteweise die Datei kopieren können, das hätte den gleichen Effekt. Nur ist damit noch nicht gesagt, dass die Bytes von den Readern/Writern auch richtig interpretiert wurden (also sie den Bytefolgen die richtigen Zeichen zugeordnet haben).

Wenn du die Zeichen korrekt ausgeben willst, musst du schon den richtigen Zeichensatz einstellen und dann auch eine Ausgabe verwenden, die mit japanischen Text umgehen kann. Nimm doch einfach eine JTextArea und weise ihr den Text zu, dann sollten wir mehr sehen (oder auch nicht).

Der Fehler mit den Arraygrenzen hat aber nichts damit zu tun (meine Vermutung).

Ark


----------



## Ikaragua (15. Aug 2008)

Wildcard hat gesagt.:
			
		

> ...
> Im code natürlich, wo sonst?


Ah, Ich sehe schon... Die allgemeine Net*t*iquette im java-forum tritt einmal mehr zutage.

Zumindest einer kümmert sich ernsthaft um die Belange anderer. Vielen Dank, Ark.

//Nachtrag:


> Nimm doch einfach eine JTextArea und weise ihr den Text zu, dann sollten wir mehr sehen (oder auch nicht)


Leider das selbe Ergebnis.


----------



## Wildcard (15. Aug 2008)

Ark hat gesagt.:
			
		

> Dass das Lesen und Schreiben funktionieren, liegt ja auch ganz einfach daran, dass die Zeichensätze beim Lesen und Schreiben übereinstimmen. Du hättest genausogut auch byteweise die Datei kopieren können, das hätte den gleichen Effekt. Nur ist damit noch nicht gesagt, dass die Bytes von den Readern/Writern auch richtig interpretiert wurden (also sie den Bytefolgen die richtigen Zeichen zugeordnet haben).


Nein, das stimmt nicht. Wenn du Reader/Writer verwendest konvertierst du in Java Strings wenn danach noch alles passt, war das Encoding in Ordnung und der String kam sauber an. Der Fehler liegt also an anderer Stelle.



> Ah, Ich sehe schon... Die allgemeine Nettiquette im java-forum tritt einmal mehr zutage.


Die Nettiquette gebietet sinnvolle Problembeschreibungen zu liefern. Du wirfst lediglich mit Vermutungen und Informationsbrocken um dich.


----------



## Ark (15. Aug 2008)

> Leider das selbe Ergebnis.


Tja, dann stimmt wohl der Eingangszeichensatz nicht. Kennst du den Zeichensatz des Textes bzw. hast du Einfluss auf ihn?

Und was ist mit dem Arraygrenzenfehler? Da wir momentan wohl zwei Fehler behandeln, wäre es besser, wenn du jedes Mal sagen würdest, welcher der Fehler noch immer auftritt.

Ark


----------



## Ark (15. Aug 2008)

Wildcard hat gesagt.:
			
		

> Nein, das stimmt nicht. Wenn du Reader/Writer verwendest konvertierst du in Java Strings wenn danach noch alles passt, war das Encoding in Ordnung und der String kam sauber an. Der Fehler liegt also an anderer Stelle.


Wann ist "danach"? Dass die Strings nach Einlesen mit falschem Zeichensatz ziemlichen Müll enthalten, ist mir schon klar, aber wenn genau dieser Müll mit genau dem gleichen Zeichensatz wieder herausgeschrieben wird (z.B. in eine Datei), dann entsteht auch ein identischer Bytestrom.

Ark


----------



## Ikaragua (15. Aug 2008)

Ark hat gesagt.:
			
		

> Tja, dann stimmt wohl der Eingangszeichensatz nicht. Kennst du den Zeichensatz des Textes bzw. hast du Einfluss auf ihn?


Ich habe den Text selbst verfasst und Unicode-codiert als Textdokument gespeichert. Hier kannst du es dir selbst anschauen: Saetze.txt



> Und was ist mit dem Arraygrenzenfehler? Da wir momentan wohl zwei Fehler behandeln, wäre es besser, wenn du jedes Mal sagen würdest, welcher der Fehler noch immer auftritt.


Die Angelegenheit mit dem Arraygrenzenfehler ist behoben. Die Ursache für ihn war das ledigliche Vorkommen eines jap. Schriftzeichens im Textdokument.


----------



## Wildcard (15. Aug 2008)

Ark hat gesagt.:
			
		

> Wann ist "danach"? Dass die Strings nach Einlesen mit falschem Zeichensatz ziemlichen Müll enthalten, ist mir schon klar, aber wenn genau dieser Müll mit genau dem gleichen Zeichensatz wieder herausgeschrieben wird (z.B. in eine Datei), dann entsteht auch ein identischer Bytestrom.


Ach, ist das so? Dann schreib mal eine binärdatei mit einer BufferedReader/Writer Kombination.
Wenn das Ding korrekt auf einen Java String gemappt werden kann, und es anschließend richtig wieder raus kommt, ist es sehr wahrscheinlich das richtige Encoding (oder Glück).


----------



## Ark (15. Aug 2008)

Ikaragua hat gesagt.:
			
		

> Saetze.txt


Die Datei ist in UTF-16LE kodiert. Bitte verwende diesen Zeichensatz (und teste dann mit Swing).

Ark

@Wildcard: Warum sollte es nicht funktionieren, wenn ich immer jeweils als Ein- und Ausgabekodierung ISO-8859-1 verwende? Die Strings sind u.U. Schrott, genauso wie die Bytes, wollte man die einzelnen chars mit &0xFF casten. Aber nur zum Rein- und Wiederrausschreiben sollte es funktionieren.

Ark


----------



## Ikaragua (15. Aug 2008)

Ark hat gesagt.:
			
		

> Die Datei ist in UTF-16LE kodiert. Bitte verwende diesen Zeichensatz (und teste dann mit Swing).
> 
> Ark


Wie hast du das festgestellt? Alles, was mir angibt, welchen Zeichensatz es hat, gibt Unicode an.

//Nachtrag:
Oh. Das was ich Unicode nenne, ist UTF-16LE.


----------



## Ark (15. Aug 2008)

Ikaragua hat gesagt.:
			
		

> Ark hat gesagt.:
> 
> 
> 
> ...


UTF-Zeichensätze _sind_ Unicode-Zeichensätze (Wikipedia hilft  ). Dass es ausgerechnet UTF-16LE sein sollte, hat Firefox entweder vermutet oder herausgelesen (an einer BOM, Byte Order Mark, auch hier hilft Wikipedia  ). Jedenfalls werden mir die Hiragana usw. korrekt wiedergegeben.

"Unicode" als Bezeichnung für einen Zeichensatz ist leider nicht eindeutig. Im Wikipediaartikel über UTF-8 (u.a.) sollten auch andere Unicode-Zeichensätze genannt sein.

Ark


----------



## Wildcard (15. Aug 2008)

Ark hat gesagt.:
			
		

> @Wildcard: Warum sollte es nicht funktionieren, wenn ich immer jeweils als Ein- und Ausgabekodierung ISO-8859-1 verwende? Die Strings sind u.U. Schrott, genauso wie die Bytes, wollte man die einzelnen chars mit &0xFF casten. Aber nur zum Rein- und Wiederrausschreiben sollte es funktionieren.


Dann versuch es. Nimm ein JPEG.


----------



## Ikaragua (15. Aug 2008)

来た!

Es funktioniert! Vielen Dank, Ark!


----------



## Ark (15. Aug 2008)

@Ikaragua: Mir ist gerade spontan beim Lesen aufgefallen, dass es an einer Stelle というきせい (to i u ki se i) heißt, während in der Umschrift "to yuu kisei" geschrieben wird, was ich spontan in とゆうきせい transkribiert hätte. Was stimmt denn nun? oO

Ark


----------



## Ikaragua (15. Aug 2008)

Ark hat gesagt.:
			
		

> @Ikaragua: Mir ist gerade spontan beim Lesen aufgefallen, dass es an einer Stelle というきせい (to i u ki se i) heißt, während in der Umschrift "to yuu kisei" geschrieben wird, was ich spontan in とゆうきせい transkribiert hätte. Was stimmt denn nun? oO
> 
> Ark


-> PN


----------



## Ark (15. Aug 2008)

Ikaragua hat gesagt.:
			
		

> 来た!
> 
> Es funktioniert! Vielen Dank, Ark!


どう致しまして 

アーク


----------



## Ark (15. Aug 2008)

@Wildcard: Funktioniert einwandfrei. 

Ark


----------



## Wildcard (15. Aug 2008)

Nein, tut es nicht.

```
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;


public class BufferedFailure {

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		File source = new File("picture.jpg");
		File target = new File("borkenPicture.jpg");
		BufferedReader in = new BufferedReader(new FileReader(source));
		String tmp = null;
		PrintWriter writer = new PrintWriter(new FileWriter(target));
		while((tmp = in.readLine())!=null)
		{
			writer.println(tmp);
		}
		
		in.close();
		writer.close();
	}

}
```


----------



## Ark (15. Aug 2008)

```
/**
 * 
 */
package test;

import java.io.*;


/**
 * @author ark
 *
 */
public final class RWCopy{

	/**
	 * @param args
	 * @throws FileNotFoundException 
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception{
		Reader r=new BufferedReader(new InputStreamReader(new FileInputStream(new File("testbild.jpg")),"ISO-8859-1"));
		Writer w=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("testbild_ergebnis.jpg")),"ISO-8859-1"));
		int x;
		while((x=r.read())>=0){
			w.write(x);
		}
		w.close();
		r.close();
	}
}
```
Ark


----------



## Wildcard (15. Aug 2008)

```
public final class RWCopy{

   /**
    * @param args
    * @throws FileNotFoundException
    * @throws Exception
    */
   public static void main(String[] args) throws Exception{
      Reader r=new BufferedReader(new InputStreamReader(new FileInputStream(new File("testbild.jpg")),"UTF-8"));
      Writer w=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("testbild_ergebnis.jpg")),"UTF-8"));
      int x;
      while((x=r.read())>=0){
         w.write(x);
      }
      w.close();
      r.close();
   }
}
```
Und jetzt?  :wink:


----------

