# Premature end of file



## SpammerSlammer (23. Feb 2010)

Hallo,

ich habe ein Programm geschrieben, das XML als Format zum Abspeichern der im Programm bearbeiteten Textdaten benutzt. Parsen und Speichern der Dateien mache ich mit JDOM. Die Daten werden mit dem UTF-8-Zeichensatz gespeichert.

Nun ist es bei mehreren Dateien passiert, dass der SaxBuilder gesagt hat:

```
Error on line 2 of document file:/D:/file.xml: Premature end of file.
```
Interessanterweise tritt dieses Problem bei drei Rechnern (Windows Vista) auf, während sechs weitere Rechner (Vista, XP, MacOS, Ubuntu) mit denselben Dateien und demselben Programmcode das Problem nicht haben. Auch der in Firefox integrierte Parser meldet, dass die Dateien valide sind. Das müssen sie auch sein, immerhin hat mein Programm sie mit Hilfe des JDOM XMLOutputters geschrieben.

Wenn ich mir die ersten drei Zeilen der XML-Datei ansehe, sieht das wie folgt aus:

```
<?xml version="1.0" encoding="utf-8"?>
<discourse>
  <version>1.09</version>
```
Eigentlich ist also in Zeile 2 gar nichts zu bemängeln.

Wie kann ich nun herausfinden, was da schief läuft? Danke für Eure Hinweise im Voraus!


----------



## Noctarius (23. Feb 2010)

Liegt vermutlich an der Version (bzw dem verwendeten) Sax Parser. Wie sieht denn der Rest des Codes aus, der das File liest?

Normal passiert sowas wenn mehrere Dinge nacheinander oder gleichzeitig versuchen den selben InputStream zu lesen.


----------



## SpammerSlammer (24. Feb 2010)

Hm, eigentlich nutzen mehrere Dutzend Leute mein Programm schon seit Monaten, und das Problem ist vorher nie aufgetreten. Ich halte es daher für unwahrscheinlich, dass das Problem in dem Code selbst zu suchen ist. Aber hier ist er:


```
//Die Variable filename wird der Klasse vorher übergeben.
try {
    SAXBuilder builder = new SAXBuilder( false );
    Document docXml = builder.build( new File( filename ) );
    Element discourse = docXml.getRootElement();

    Element version = (Element) discourse.getChildren().get(0);
    String v = version.getText();
    System.out.println(v);

    for (int i = 1; i < discourse.getChildren().size(); i++) {

        //create article with title, date and text
        Element article = (Element)discourse.getChildren().get(i);
        Element text = (Element) article.getChild("text");
        String articleText = new String("");
        for (Iterator<?> j = text.getContent().iterator(); j.hasNext( ); ) {
            Object o = j.next( );
            if (o instanceof Text) {
                articleText = articleText + ((Text)o).getText();
            } else if (o instanceof CDATA) {
                articleText = articleText + ((CDATA)o).getText();
            } else if (o instanceof Comment) {
                articleText = articleText + ((Comment)o).getText();
            } else if (o instanceof ProcessingInstruction) {
                articleText = articleText + (ProcessingInstruction)o;
            } else if (o instanceof EntityRef) {
                articleText = articleText + (EntityRef)o;
            } else if (o instanceof Element) {
                articleText = articleText + "<" + ((Element)o).getName() + "/>";
            }
        }
        articleText = articleText.replaceAll("\n", "<br />");
        String dateString = article.getChild("date").getText();
        String title = article.getChild("title").getText();
        Date date = new Date();
        try {
            SimpleDateFormat sdfToDate = new SimpleDateFormat("dd.MM.yyyy");
            date = sdfToDate.parse(dateString);
            //Hier werden dem Hauptprogramm die Variablen title, date 
            //und articleText übergeben. Ich habe es der Übersicht halber entfernt.
        } catch (ParseException pe) {
            pe.printStackTrace();
        }

        //create statements
        Element statementsXml = (Element) article.getChild("statements");
        for (int j = 0; j < statementsXml.getChildren().size(); j++) {
            Element statement = (Element) statementsXml.getChildren().get(j);
            int id = Integer.parseInt(statement.getChild("id").getText());
            String start = statement.getChild("start").getText();
            String end = statement.getChild("end").getText();
            String person = statement.getChild("person").getText();
            String organization = statement.getChild("organization").getText();
            String category = statement.getChild("category").getText();
            String agreement = statement.getChild("agreement").getText();
            int startInt = Integer.valueOf( start ).intValue();
            int endInt = Integer.valueOf( end ).intValue();
            String selection = articleText.replaceAll("<br />", "\n");
            try {
                if (endInt > selection.length() + 1) {
                    endInt = selection.length() + 1;
                    System.out.println("End position of statement " + id + " was corrected.");
                }
                if (startInt > selection.length()) {
                    startInt = selection.length();
                    System.out.println("Start position of statement " + id + " was corrected.");
                }
                selection = selection.substring(startInt-1, endInt-1);
            } catch (StringIndexOutOfBoundsException e) {
                System.out.println("Statement text of statement " + id + " could not be identified.");
            }

        //An dieser Stelle werden dann die Variablen id, startInt, endInt, date, selection, 
        //title, person, organization, category und agreement dem Hauptprogramm übergeben.
        //Ich habe es der Übersicht halber entfernt.

        }
    }
} catch (OutOfMemoryError ome) {
    System.out.println("Out of memory.");
} catch (IOException e) {
    System.out.println("Error while reading the file \"" + filename + "\": " + e.getMessage());
} catch (org.jdom.JDOMException e) {
    System.out.println("Error while opening the file \"" + filename + "\": " + e.getMessage());
}
```


----------



## Noctarius (24. Feb 2010)

Hast du mal geschaut ob in dem File eventuell nicht druckbare Zeichen wie char(0) = EndOfString vorkommen? Wenn es nur ein File ist, vielleicht hilft es dann auch, den angezeigten Inhalt im Editor einfach mal in ein anderes File zu kopieren.


----------



## Niki (24. Feb 2010)

Mach einmal die xml-Datei in der cmd-Konsole auf. (edit)
Eventuell findest du gleich am Anfang ein komische Zeichenfolge. Lösch die mal raus wenn die vorhanden ist.


----------



## SpammerSlammer (24. Feb 2010)

Das Problem ist bei einer Forschergruppe in England aufgetreten. Sie haben mir zwei der fehlerhaften Dateien dann per Mail zugeschickt. Es könnte also theoretisch sein, dass sie mir aus Versehen zwei Dateien geschickt haben, die funktionieren. Ich werde sie bitten, dass noch einmal gründlich zu prüfen.

Könnte es theoretisch sein, dass durch das Anhängen an eine E-Mail die nicht-druckbaren Escape-Zeichen durch den Mailserver automatisch entfernt werden? Oder dass innerhalb der Forschergruppe bei dem Verteilen der Datei per E-Mail Escape-Zeichen durch den Mailserver hinzugefügt werden, die in meiner Datei nicht vorhanden sind, weil ich die Datei über einen anderen Mailserver erhalten habe?

Ich habe die beiden Dateien jedenfalls mit pico, vi und gedit auf Escape-Sequenzen untersucht und nichts gefunden. Zumindest vi hätte ja etwas anzeigen müssen. Es hätte mich auch gewundert, denn innerhalb meines Programms setze ich einen DocumentFilter ein, um alle unliebsamen Escape-Zeichen von vorn herein zu unterbinden.

Oder wäre es vielleicht denkbar, dass der Fehler durch unterschiedliche Versionen der JRE verursacht wird?


----------



## Noctarius (24. Feb 2010)

Ich bin mir nicht sicher was die Base64 Kodierung aus Escape-Zeichen macht. Sie sollen die 2 Dateien am besten einmal in ein ZIP packen und dann per Mail verschicken.

In einem ganz seltenen Fall könnte es auch an der Java-Version liegen. Du solltest mal die Java-Version anfragen und es eventuell mit der gleichen Version testen. Vielleicht würde dann ein Update auf eine neuere Version helfen.


----------



## SpammerSlammer (24. Feb 2010)

Genau diese beiden Sachen habe ich ihnen heute morgen schon vorgeschlagen. Ich warte dann mal auf die Antwort und melde mich ggf. noch mal. Danke schon mal für die bisherige Diskussion.


----------

