Zum Dateianfang zurückspringen

Status
Nicht offen für weitere Antworten.

cyliax

Mitglied
Hallo, ich möchte nach einmaligem Auslesen der erste Zeile einer Datei, das Auslesen wieder am Anfang der Datei fortsetzen. Ich habe deshalb mal ein bißchen mit mark(), reset() und marksupported() experimentiert, werde aber nicht so richtig schlau aus der Funktionsweise. Hier erstmal ein Stück Code:

Code:
BufferedReader b_in = new BufferedReader ( new FileReader(path) );

if (b_in.markSupported())
{
	b_in.mark(1); // Markieren des Dateianfangs
	
	if (!b_in.readLine().contains("$Date")) // Überprüfen ob erste Zeile $Date enthält
	{
		b_in.reset(); // Zurücksetzen zum Dateianfang
		BufferedWriter b_out = new BufferedWriter ( new FileWriter(path+".tmp") );

		int i = 0;
		while( (i = b_in.read()) != -1 ) b_out.write(i); // Kopieren des Inhalts von Datei b_in nach b_out

		b_in.close();
		b_out.close();
	}
}

So ganze klappt wenn in der Datei, sagen wir mal test.txt mehr als eine Zeile vorhanden ist. Dann wird alles Ordnungsgemäßt übertragen, wenn jedoch nur eine Zeile da ist, dann gibt es eine Exception. Ich nehme mal an das hat irgendwas mit diesem mark(1) und reset() zu tun?

Weiß da jemand einen Rat für mich bzw kennt eine grundsätzlich bessere Methode nach einem readLine() zum Dateianfang zurückzukehren?

Danke im Voraus
 

dieta

Top Contributor
Ich würde mal sagen: Speichere einfach alles in einen String, mit dem kannst du dann machen, was du willst.
 

cyliax

Mitglied
ja das mit dem string hatte ich auch schon überlegt. allerdings weiß ich nicht wie groß die dateien werden die hier maximal gescannt und geschrieben werden, daher hatte ich angst, das dann damit irgendwo was schief geht. wie groß darf denn ein string so maximal sein. passen da auch dateien von mehreren megabyte größe rein oder gibts da irgendeine beschränkung? und wie sieht das mit dem format aus... unter umständen sind in den gescannten dateien wilde zeichen (also ascii 0-255 drin), die müssen alle unverändert erhalten bleiben...?

außerdem würde ich mit nem string dateien einlesen die ich vielleicht später garnicht brauche, fände das also nicht so performant.
 

dieta

Top Contributor
Für die Performance kannst du das ganze mit einem StringBuilder machen. Der ist schneller als jedes mal ein += hinzuschreiben, weil da immer ein neuer StringBuilder erzeugt wird (VM-Intern).
Strings und der StrinBuilder haben als einzige Größenbeschränkung so weit ich weis den Heap der VM. Die Größe dürfte also eigentlich nicht das Problem sein.
Exotische Zeichen dürften auch kein Problem sein da JavaUnicode unterstützt.
 

cyliax

Mitglied
ich danke dir erstmal für deine hilfe. das mit dem string wäre in der tat ne möglichkeit gewesen. aber ich habs jetzt doch ein bißchen einfacher gelöst, obs performanter ist wage ich jetzt mal zu bezweifeln.

also das ganze mark() marksuppurted() und reset() raus und die datei einfach innerhalb der if bedingung wieder mit in.close() schließen und ne zweite instanz der datei erstellen und dann damit weiter arbeiten. klingt etwas plump funktioniert aber bestens und ich nicht ganz so verwirrend.

Code:
BufferedReader b_in = new BufferedReader ( new FileReader(path) );

//if (b_in.markSupported())
//{
   //b_in.mark(1); // Markieren des Dateianfangs
   
   if (!b_in.readLine().contains("$Date")) // Überprüfen ob erste Zeile $Date enthält
   {
      //b_in.reset(); // Zurücksetzen zum Dateianfang
      b_in.close();
      BufferedReader b_in2 = new BufferedReader ( new FileReader(path) );
      BufferedWriter b_out = new BufferedWriter ( new FileWriter(path+".tmp") );

      int i = 0;
      while( (i = b_in2.read()) != -1 ) b_out.write(i); // Kopieren des Inhalts von Datei b_in nach b_out

      b_in2.close();
      b_out.close();
   }
//}
 

rik0

Mitglied
ich würde die komplette Datei erstmal in einen Vektor einlesen. Der ist dynamisch - es ist also egal, wie groß die Datei ist. Danach kannst Du die einzelnen Zeilen nach belieben weiterverarbeiten:

Code:
  public void go() {
	  Vector<String> lines = new Vector<String>();
	  
	  try {
		FileReader fr = new FileReader("C:\\temp\\my.txt");
		BufferedReader br = new BufferedReader(fr);
		String temp;
		
		while ((temp = br.readLine()) != null) {
			lines.add(temp);
		}
		
		br.close();
		fr.close();
		
	} catch (Exception e) {
		e.printStackTrace();
	}
	
	System.out.println(lines.size());  //anzahl zeilen ausgeben
	System.out.println(lines.get(4)); //5. Zeile ausgeben
	System.out.println();
	
	//alle zeilen ausgeben
	for (String s: lines) {
		System.out.println(s);
	}
	  
  }
 
G

Guest

Gast
hi rik0, ich danke auch dir für deine rege anteilnahme. die entwicklung dieses kleinen tools ist bereits abgeschlossen. das nächste mal, mache ich es aber auch auf diesem weg. das mit dem vektor erscheint mir sehr einleuchtend und einfach.

klasse forum!!!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben