# Speichern einer Datei in UTF-16



## Gelöschtes Mitglied 12486 (29. Sep 2010)

Hallo,

ich habe einen kleinen Editor gebastelt, welcher eine bestimmte Art von Textdatei einliest und auf Fehler prüfen kann. Die Fehler können dann im Editor direkt behoben werden. 

Wie gesagt liegt die Textdatei in einer UTF-16 Kodierung vor. Ich lese die Datei dann folgendermaßen ein:

```
in = new LineNumberReader(new InputStreamReader(new FileInputStream(file), "UTF-16"));
String input = null;
while ((input = in.readLine()) != null) {...}
```

Ich durchlaufe die Datei dann per while-Schleife und prüfe per if-Abfragen ob das vorliegende Format der bestimmten Zeilen korrekt ist. Nicht schön, aber funktioniert  

Ich speichere die Datei nach der Bearbeitung folgendermaßen ab:


```
public void saveTextGrid() {
        exec.execute(new Runnable() {
            public void run() {
                if (fileChooser != null) {
                    int retValue = fileChooser.showSaveDialog(DesktopApplication1.getApplication().getMainFrame());
                    if (retValue == JFileChooser.APPROVE_OPTION) {
                        MySplitPane pane = (MySplitPane) jTabbedPane1.getSelectedComponent();
                        String text = pane.getTextgridPanel().getText();
                        try {
                            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileChooser.getSelectedFile()), "UTF-16"));
                            out.write(text.toCharArray());
                            out.flush();
                            out.close();
                            pane.getTextgridPanel().setTextChanged(false);
                            pane.getTextgridPanel().setFile(fileChooser.getSelectedFile());
                            pane.getTextgridPanel().readTextWithFileChannel(fileChooser.getSelectedFile());
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        });
    }
```

Mein Problem besteht nun darin, dass ich anscheinend etwas beim Speichern der korrigierten Datei falsch mache. Ich weiß jedoch noch nicht genau was. Wenn ich die Datei nun im Editor anzeige (in einer JTextArea), dann sehe ich in Zeile 1 folgendes(ohne äußere ""):


```
File type = "ooTextFile"
```

Wenn ich mir die Datei jedoch per System.out.println() in der Konsole ausgeben lasse, so steht in der ersten Zeile etwas wie das hier:


```
"````File type = "ooTextFile""
```

Es tauchen diese Punkte/Striche/Apostrophe vor der ersten Zeile auf, was natürlich meine einfach gestrickte if-Abfrage aushebelt, da diese nur auf den Zeilenanfang schaut. Somit wird die Zeile nicht mehr korrekt geprüft.

Wie entstehen nun diese komischen Zeichen in der ersten Zeile? Meine Vermutung ist, dass die Anzahl der Striche etwas mit der Anzahl der Speichervorgänge zu tun hat, aber so richtig reproduzieren konnte ich das auch nicht. Hat jemand eine Idee woher das kommt?

edit:

Durch das Erstellen dieses Posts hab ich nun gesehen, dass es sich um dieses Zeichen handelt. Kann mir jemand erklären wie das an den Anfang meiner Datei gelangt?

Ich habe den Speichervorgang mittlerweile so abgeändert, dass die Zeichen in einer For-Schleife einzeln in die Datei geschrieben werden und nicht in einer Zeile per out.write(text.toCharArray());. Jedoch macht das keinen Unterschied.

Gruß
huetz


----------



## Atze (29. Sep 2010)

woher sie kommen kann ich dir nicht sagen, aber vielleicht kannst du als krücke erstmal replaceAll("\uFEFF","") drüberlaufen lassen, bist du weißt wie du das verhinderst! ist nicht schön, aber dann sind sie wenigestens erstmal weg!


----------



## Gelöschtes Mitglied 12486 (29. Sep 2010)

Danke für den Tip mit dem Replace, ich werde es zur Not so machen 

Ich habe mir nun ein paar mal die Textdateien ausgegeben und dabei bemerkt, dass anscheinend nicht das Speichern, sondern das Öffnen der Datei zu dem unerwünschten Zeichen führt. Ich öffne die Datei, in dem ich erst per JFileChooser die Datei auswähle und an das anzuzeigende Panel übergebe. Dieses speichert in seiner Initialisierung die Datei als File erstmal und startet dann die Methode readTextWithFileChannel(File file).


```
public void openTextGrid() {
        exec.execute(new Runnable() {
            public void run() {
                if (fileChooser != null) {
                    fileChooser.setDialogTitle("choose a textgrid...");
                    fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                    int retValue = fileChooser.showOpenDialog(DesktopApplication1.getApplication().getMainFrame());
                    if (retValue == JFileChooser.APPROVE_OPTION) {
                        String filename = fileChooser.getSelectedFile().getName();
                        MySplitPane split = new MySplitPane(new TextgridPanel(fileChooser.getSelectedFile()));
                        jTabbedPane1.add(filename, split);
                    }
                }
            }
        });
    }
```

Hier die Methode readTextWithFileChannel(File file):


```
protected void readTextWithFileChannel(File file) {
        long start = 0, end = 0;
        try {
            start = System.currentTimeMillis();
            FileChannel inChannel = new FileInputStream(file).getChannel();
            ByteBuffer buf = ByteBuffer.allocate(8192);// 8K

            Document doc = textArea.getDocument();
            String temp = null;

            while (inChannel.read(buf) != -1) {
                temp = ((ByteBuffer) (buf.flip())).asCharBuffer().toString();
                doc.insertString(doc.getLength(), temp, null);
                buf.clear();
            }
            textArea.setDocument(doc);
            setTextChanged(false);
            inChannel.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            end = System.currentTimeMillis();
        }
        long time = (end - start);
        System.out.println("Datei \"" + file.getAbsolutePath() + "\" geöffnet, " + time + " ms");
    }
```

Die Vermutung liegt nah, dass ich irgendwas bei der Verwendung des FileChannels falsch mache. Jedoch hab ich natürlich keine Ahnung was das sein könnte  Ich verwende diese Methode die Datei zu öffnen, da ich gelesen habe, dass sie schneller sein soll als die herkömmliche Methode per Stream. Zur Not kann ich aber auch darauf zurück wechseln. 

Hat dazu jemand eine Idee wie die Zeichen in den Text kommen?


----------



## KrokoDiehl (29. Sep 2010)

Was ich bei der Methode die einliest, nicht finde, ist die Zeichenkodierung. Auch wenn die Datei selbst in UTF-16 vorliegt würde ich spontan darauf tippen, dass der _FileInputStream_ (Zeile 5 im geposteten Code) eine andere Kodierung nimmt, z.B. den Systemstandard.
Hier würde ich also mal probieren die Kodierung anzugegeben.


----------

