# Ans Ende einer txt Datei schreiben



## Der Seppl (4. Jan 2008)

Hi!

Wie kann ich ans Ende einer txt-Datei, die bereits existiert und Daten beinhaltet, schreiben?

In der txt steht z.B.


```
text1
text2
text3
```

und ich würde gern jeweils Daten nach der letzten zeile schreiben. Bisher wird der Inhalt meiner Datei immer wieder überschrieben.

Umgekehrt möchte ich jeweils nur die letzte Zeile wieder einlesen, wie schaffe ich das?

Danke im Voraus!
der Seppl


----------



## The_S (4. Jan 2008)

Du kannst deinem FileWriter/FileOutputStream neben der Zieldatei noch einen boolean mitgeben. Dieser legt fest, ob angehängt, oder überschrieben werden soll.


----------



## Der Seppl (4. Jan 2008)

Oh, das war ja einfach, danke 

Aber wie funktioniert es "umgekehrt", also dass ich beim einlesen nur die letzte Zeile erhalte bzw. die letzte Zeile von den anderen unterscheiden kann?

Danke!


----------



## The_S (4. Jan 2008)

Du musst bis zur letzten Zeile alles einlesen. Dateien sind sequentiell aufgebaut, d. h. du kannst nicht einfach vom Ende oder mittendrin anfangen zu lesen.


----------



## Der Seppl (4. Jan 2008)

Und welche Möglichkeit gibt es dann, die Zeilen voneinander zu unterscheiden?

Ich mein, wenn ich laufend in die Datei reinschreibe (unterschiedl. Werte), woher weiss ich dann welcher Wert der letzte ist?


----------



## masta // thomas (4. Jan 2008)

Naja, weil es eben der letzte Wert in der Datei ist  Du liest zeilenweise ein, letzte Zeile = letzter Eintrag


----------



## MiMij (4. Jan 2008)

Du kannst Zeile fuer Zeile die Textdatei einlesen, und wenn nach der aktuellen Zeile keine mehr kommt, ist doch klar das du dann bei der letzten bist


----------



## MASTERmind (4. Jan 2008)

Wichtig ist vor allem, dass Du ein Muster in den Datei Inhalten erkennst und dieses dann benutzt für die Dinge, die Du anstellen willst.
Du könntest den Inhalt der Datei auch in eine HashMap stopfen zum Beispiel


```
Map<Integer,String> myMap = new HashMap<Integer,String>();
```

Dann hast Du zu jeder Zeile einen Index und kannst zum Beispiel, falls gewünscht, doppelte Zeilen in Deiner Datenmenge myMap ausschliessen mit 


```
if(!myMap.contains(zeile))
{
  myMap.add(zeile);
}
```

myMap kannst Du dann mit einem FileWriter wieder in die Datei schreiben....


----------



## Shadeo (4. Jan 2008)

Eine HashMap hat keine Methode add(), sondern put(), wo du Key und Value angeben musst. Funktioniert natürlich auch, dazu musst du aber die Zeilen selber zählen lassen. Auf doppelte Einträge prüfen könntest du dann mit containsValue()

--> ArrayList wäre wohl besser, dann musst du die Zeilennummer nicht manuell mitzählen


----------



## Der Seppl (4. Jan 2008)

Hab es jetzt etwas anders gelöst, trotzdem danke für eure Hilfe!

Habe aber noch ein Problem... und zwar schreibe ich in die txt-Datei eine Zahl und danach ein Datum.
Beim Einlesen zerlege ich diese Strings um nur die Zahl zu erhalten.

Führe ich das ganze als Java Anwendung aus, funktioniert es. Aber so bald ich die Klasse als JavaBean in eine jsp einbinden will, erhalte ich eine "NumberFormatException" für den String "null". Bedeutet ja im Umkehrschluss, dass der Wert, den er aus der Datei liest null ist.

Aber warum funktioniert es einwandfrei, wenn es als reine java anwendung ausgeführt wird und sonst nicht?
Habt ihr dazu eine Idee?

danke für eure Hilfe!


----------



## SlaterB (4. Jan 2008)

blind geraten: die JSP wird von woanders ausgeführt und findet daher den relativen Pfad nicht,

für richte Erklärung: Code+ Umgebung posten (was bei JSPs nicht gerade trivial ist)/ 
selber suchen: Datei anschauen: wird sie gefunden?, ist die Dateigröße gleich?, welche Strings werden zeilenweise eingelesen ohne gleich zerlegen/ parsen zu wollen?,
mit einfacherer Datei nur mit einem Buchstaben x testen


----------



## Der Seppl (4. Jan 2008)

Also zur Umgebung: arbeite mit Tomcat und Easy Eclipse.

JSP Seite bindet nur als JavaBean ein, die betroffende Methode wird innerhalb der Klasse aufgerufen:


```
idManager idMan = new idManager();

public String getid() {

		int new_id = idMan.getID();

		idMan.setID(String.valueOf(new_id), getName());

		return new_id;
}
```

Hier aufgerufen werden diese Methoden:

getID() liefert die letzte ID, die in der Textdatei steht:

```
public Integer getID(){
		try{
			String zeile = "";
			java.io.BufferedReader versionReader  = new java.io.BufferedReader(new java.io.FileReader("version.txt"));
			java.util.ArrayList<String> Ids = new java.util.ArrayList<String>();

			while((zeile = versionReader.readLine()) != null ) {

			    String[] result = zeile.split("     ");
			    for(int x = 0; x < result.length; x++)
			    	Ids.add((result[x]));
			}
			versionReader.close();

			int anzahlIds = Ids.size();
			if(!Ids.get(anzahlIds - 1).equals("null") || Ids.get(anzahlIds - 1) != null){
				zeile = Ids.get(anzahlIds - 2);
			}else{
				zeile = Ids.get(anzahlIds - 4);
			}
			System.out.println(String.valueOf(Integer.parseInt(zeile) + 1));

			return Integer.parseInt(zeile) + 1;

		}catch (IOException e) {
			// Fehlerbehandlung
		}
		return 0;

	}
```

setID(id, name) schreibt in die txt Datei die neueste ID, das Datum und ein Name

```
public void setID(String newID, String catalog_name){

		try{

			java.io.FileWriter versionWriter  = new java.io.FileWriter("version.txt", true);

			SimpleDateFormat formatter = new SimpleDateFormat ("dd.MM.yyyy - HH:mm:ss");
			java.util.Date date = new java.util.Date();


			versionWriter.write(System.getProperty("line.separator") + newID + "     " + formatter.format(date) + " " + catalog_name);
			versionWriter.flush();
			versionWriter.close();

		}catch (IOException e) {
			// Fehlerbehandlung
		}
	}
```

Die Textdatei ist wie folgt aufgebaut:

```
// Diese Textdatei dient zum Speichern der Katalog-IDs
1     04.01.2008 - 15:13:14 der Seppl
```

Wie gesagt, zur JSP gibt es nicht viel zu schreiben, da sie die Bean einbindet und eine Methode aufruft. Diese Methode wiederrum ruft die getid() auf.

Danke für die Hilfe.


----------



## Der Seppl (6. Jan 2008)

Hallo!

Habe den Fehler gefunden, verstehe ihn aber nicht so ganz.
Hab durch ein paar Ausgaben auf der Konsole rausgefunden, dass JBoss auf eine andere Datei zugreift als die Java Klasse.
Wenn ich die Klasse alsAnwendung ausführe wird die txt-Datei aus meinem Projektordner zum Lesen / Schreiben verwendet.
Binde ich die Klasse als JavaBean ein, wird eine txt-Datei im JBoss bin-Ordner verwendet... aber warum?

Ich wollte ja eigentlich, dass die txt-Datei immer beim Projekt dabei ist und nicht einfach im JBoss Ordner neu erstellt wird...

...woran kann das liegen?

der Seppl


----------



## The_S (7. Jan 2008)

Weil ein relativer Pfad immer dort beginnt, von wo aus die Klasse aufgerufen wird. Und nicht etwa von dort aus, wo die Klasse liegt.


----------

