# Zeilenweise löschen



## TheGreenDragon (28. April 2009)

Hallo,

kann mir jemand verraten wie ich es am geschicktesten hinbekomme, die ersten 6 Zeilen und die letzte Zeile einer Datei zu löschen?

Gruss


----------



## MiMi (28. April 2009)

Hast du dir denn schon Gedanken gemacht, wie man an die Zeilen einer Datei rankommt und wie man Zeilen loeschen kann?


----------



## TheGreenDragon (28. April 2009)

Schon aber ich komm zu nichts.

Mein erster Gedanke war eine neue Datei zu schreiben und die ersten 6 Zeilen einfach beim readLine(), nicht zu beachten. Aber wann weiss ich wann die letzte Zeile da ist damit ich sie weg lassen kann? 

Zudem tat sich dann noch ein zweites Problem auf. Die Methode write() beachtet keine Zeilenumbrüche.


```
FileWriter fw = new FileWriter(f2);

        
        for ( String line; (line = eingabe.readLine()) != null; ) 
            fw.write(line);
```
Es wird alles in eine Zeile geschrieben obwohl die Ausgangsdatei immer sowas stehen hat


```
asdlkfjlsdakfjlaskdjf


asldfjlaskdfjlsdjf


alsdfjäsdlafjk
```


----------



## MiMi (28. April 2009)

Ob es effizient ist weiss ich net, aber man koennte jede Zeile in nen Array Platz speichern. Dann weisst du automatisch wie viele Zeilen da ganze Ding hat. 
Und koenntest spezielle Zeilen beim schreiben in die neue Datei auslassen. 
Haettest auch ma googeln koenen ^^ Oder die Forensuche nutzen!
http://www.tutorials.de/forum/net-cafe/198127-feste-zeile-datei-loeschen.html


----------



## Billie (28. April 2009)

Die Datei zeilenweise einlesen und neu schreiben, aber vor jedem Schreiben überprüfen ob es eine der ersten sechs Zeilen od. die letzte Zeile ist?


----------



## zeja (28. April 2009)

Beim Zeilenweisen einlesen gehen die Zeilenumbrüche verloren. Beim schreiben musst du die also wieder dazupacken.


----------



## TheGreenDragon (29. April 2009)

@zeja

Jap das hab ich nun auch gemacht, dennoch musste ich feststellen, dass bei meinem Programm Zeichen, ja sogar ganze Zeilen verloren gehen. Die Eingangsdatei hat noch eine Größe von 751 KB aber die Ausgangsdatei nur noch 736 KB, dabei hab ich die ersten sechs noch nicht einmal weggelassen.

Wäre sehr dankbar wenn jemand den Fehler sieht:


```
File f = new File("H:/kotlett.tif");
		FileReader eingabeStrom = new FileReader(f);
		BufferedReader eingabe = new BufferedReader(eingabeStrom);
		
		File f2 = new File ("H:/schnitzel.tif");
		FileWriter fw = new FileWriter(f2);
		BufferedWriter bw = new BufferedWriter(fw);
		
		ArrayList<String> al = new ArrayList<String>();
		
		for ( String line; (line = eingabe.readLine()) != null; )
		{
			al.add(line);
			System.out.println(line);
		}
		
		for ( int i = 0; i < al.size(); i++)
		{
			bw.write(al.get(i) + "\n");
		}
```


----------



## hammet (29. April 2009)

Womit hast du denn die Ausgangsdatei erstellt?
Soweit ich weiß machen die Standart-Windows-Editoren beim zeilenumbruch immer ein "\r\n" statt einem einfachen "\n" wie bei Linux.


----------



## TheGreenDragon (29. April 2009)

@hammet

Leider bringt "\r\n" auch kein Erfolg. Seltsam ist zudem auch die Tatsache, dass bei 
	
	
	



```
System.out.println(line)
```
alle Zeilen ausgespuckt werden...


----------



## hammet (29. April 2009)

Führst du nach der zweiten For-Schleife ein "bw.flush()" aus? Das ist notwendig, damit alle Daten rausgeschickt werden. Zudem hoffe ich auch, dass du sämtliche Reader etc. closed nachdem du sie nicht emrh verwendest.


----------



## TheGreenDragon (29. April 2009)

@hammet

Sehr gut! Ich hab tatsächlich nie "geclosed" ^^ und bw.flush() hatte ich auch nicht. So die Daten sind drin, die Datei hat die gleiche Größe wenn ich alle Zeilen drin lasse. ABER aus Vierecken macht Java Fragezeichen, somit ist die Datei unbrauchbar...


----------



## Billie (29. April 2009)

Sind die Fragezeichen in der Konsole od. in der Datei selbst? Schoneinmal die Dateien mit TotalCommander/KDiff/etc. verglichen?!

Was für Dateien behandelst du eigentlich? Es spielt nämlich das Encoding eine wichtige Rolle... UTF-8, ISO 8859-1, ASCII, ... ?


----------



## TheGreenDragon (29. April 2009)

Die Fragezeichen sind in der Datei. Die Vierecke so wie sie im Original sind, sehe ich nur auf der Konsole. Verglichen habe ich das mit Notepad++.
Zeichensatz berücksichtige ich bis jetzt keinen. Wo auch?


```
File f = new File("C:/kotlett.tif");
		FileReader eingabeStrom = new FileReader(f);
		BufferedReader eingabe = new BufferedReader(eingabeStrom);
		
		File f2 = new File ("C:/schreibSchnitzel.tif");
		FileWriter fw = new FileWriter(f2);
		BufferedWriter bw = new BufferedWriter(fw);
		
		ArrayList<String> al = new ArrayList<String>();
		
		for ( String line; (line = eingabe.readLine()) != null; )
		{
			al.add(line);
			System.out.println(line);
		}
		eingabe.close();
		eingabeStrom.close();
		
		for ( int i = 0; i < al.size(); i++)
		{
			bw.write(al.get(i) + "\n");
		}
		bw.flush();
		bw.close();
		fw.close();
```


----------



## zeja (29. April 2009)

Und was soll das bezwecken ein tif so einzulesen als wäre es eine Textdatei? Natürlich gehen da haufenweise Zeichen verloren. Ist schließlich kein Text der in nem tif steht sondern Binärdaten. Entsprechend müßtest du diese auch Byteweise einlesen und schreiben.


----------



## TheGreenDragon (5. Mai 2009)

@zeja

wenn das so ist, dann habe ich folgenden Ansatz probiert. 
1. Erzeuge zwei ArrayListen
2. Lese Byteweise aus und schreibe in ArrayList2
3. Wenn ich einen Zeilenumbruch finde, dann füge ich meine ArrayList2 in die ArrayList1 ein
4. Erstelle neue ArrayList2, und mache mit Schritt zwei weiter.

Alles soweit so gut. Aber irgendwie macht das Programm nicht das was es soll. So fängt laut Notepad++ die eigentliche Datei mit Zeile 7 an. Also fange ich erst ab Zeile 7 an in die Datei zu schreiben, dennoch wird eine Leerzeile davor gehauen, so dass die Datei unbrauchbar wird. Wenn ich aber der 8 Zeile anfange fällt logischer weise die 7 weg... ?


```
File f = new File("E:/kotlett.tif");
FileInputStream fis = new FileInputStream(f);
FileOutputStream fos = new FileOutputStream("E:/schreibSchnitzel.tif");

int zeichen = 0;
ArrayList<ArrayList<Integer>> alal = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> al = new ArrayList<Integer>();

while ((zeichen = fis.read()) != -1) 
{
	if ((char) zeichen == '\n') 
	{
		alal.add(al);
		al = new ArrayList<Integer>();
	}
	al.add(zeichen);
}
fis.close();

for (int z = 6; z < (alal.size()); z++) 
{
	ArrayList<Integer> al3 = alal.get(z);
	for (int izy = 0; izy < al3.size(); izy++) 
	{
		fos.write(al3.get(izy));
	}
}
fos.flush();
fos.close();
```

Edit: Ok ich das jetzt so gelöst, dass ich bei der aller ersten Zeile das erste Zeichen weg gelassen habe, so gibt es auch keine Leerzeile am Anfang. Danke.


----------



## Thomas Darimont (5. Mai 2009)

Hallo,

hierfür gibts wie immer mehrere Möglichkeiten:
1) Datei kopieren ab der n-ten Zeile
2) Datei per RandomAccessFile öffnen und die Daten XXX Bytes nach vorne kopieren, so dass die ersten n-Zeilen überschrieben werden
3) Datei per RandomAccessFile öffnen und als erstes Zeichen in den zu "löschenden" Zeilen ein "spezielles" Zeichen verwenden, dass die Zeilen zum ignorieren kennzeichnet. Wird von der Datei wieder gelesen werden diese Zeilen ignoriert. Damit die Datei dann nicht unnötig goß anwächst wird diese dann von Zeit zu Zeit kompaktiert, in dem die zu ignorierenden Einträge rausgeworfen werden. (entweder mit Methode 1, oder 2)

Gruß Tom


----------



## TheGreenDragon (6. Mai 2009)

Ein bisschen Offtopic, aber ist das schlimm wenn man zweimal hinter einander die Methode flush() und/oder close() der Klasse FileOutputStream ausführt?


----------



## zeja (6. Mai 2009)

Bitte lies das selbst in der API nach:
http://java.sun.com/javase/6/docs/api/java/io/Closeable.html
http://java.sun.com/javase/6/docs/api/java/io/FileOutputStream.html


----------

