und zwar bräuchte ich mal einen ratschlag.
ich habe eine ca. 200mb große datei,gefüllt mit zeilen der form
"100 101 102 103 104 105 106 107 108 0"
ich möchte nun diese datei nehmen und alle zeilen anfassen und darin daten ändern.
da ich aufgrund der dateigröße die zeilen nicht in eine string variable schreiben,ändern und in eine neue datei schreiben kann,hatte ich nun vor zeilen direkt mit random acces write anzusprechen.
also:
lies zeile x,ändere zeile x, ersetze in zeile x.
das wird dann für jede zeile durchgefüht.
wie würdet ihr das machen?
Und Dein konkretes Problem? Du hast es doch schon gesagt: Zeile lesen, ändern, zurückschreiben.
Ob Du das mit einem RandomAccessFile machst oder mit einem Stream ist zumindest teilweise subjektiv.
Übrigens:
da ich aufgrund der dateigröße die zeilen nicht in eine string variable schreiben,ändern und in eine neue datei schreiben
Du mußt ja nicht gleich die ganze Datei in einen String packen. Was spricht dagegen bei einem Input-Stream bis zum nächsten CRLF zu lesen? Die Abfrage ist halt etwas weniger bequem als bei RandomAccessFile, aber prinzipiell würde ich einen Input- und einen Output-Stream nehmen und das darüber abfackeln.
File f = new File( "CNF/test.cnf" );
byte buffer[] = new byte[ (int) f.length() ];
FileInputStream in = null;
try
{
in = new FileInputStream( f );
int len = in.read( buffer, 0, (int) f.length() );
String str = new String( buffer, 0, len );
System.out.println( str + " stop" );
}
catch ( IOException e ) { System.out.println( e ); }
finally { try { if ( in != null ) in.close();} catch (IOException e) {} }
das liest nun meine komplette datei ein.
ich will aber immer nur eine zeile einlesen und auch gleich wieder schreiben,nachdem ich sie bearbeitet habe.
mein problem ist,dass ich nicht weiss wie ich immer nur eine zeile einlese und nach bearbeitung die selbe zeile wieder schreibe (diese zeile kann nach bearbeitung auch weniger zeichen enthalten)
ich hab es schon mit for schleifen versucht (also alle zeichen lesen,bis "\n" dabei ist und die länge merken etc)
aber das hat nicht geklappt.
Zum Beispiel so (mal schnell geschnitzt, in Teilen u. U. verbesserungswürdig):
Code:
import java.io.*;
public class Test {
File fin;
File fout;
FileInputStream fis;
FileOutputStream fos;
int i = 0;
public static void main(String[] args) {
new Test();
}
public Test() {
createStreams();
StringBuffer sb = new StringBuffer();
try {
do {
i = fis.read();
sb.append((char) i);
if (i == 10) {
String line = modifyLine(sb);
writeLine(line);
sb = new StringBuffer();
}
} while (i != -1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
closeStreams();
System.out.println("fertig");
}
private void createStreams() {
fin = new File("C:\\readme.txt");
fout = new File("C:\\writeme.txt");
try {
fis = new FileInputStream(fin);
fos = new FileOutputStream(fout);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private void closeStreams(){
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String modifyLine(StringBuffer change){
//mach irgendwas
return change.toString().replaceAll("Z", "Ts");
}
private void writeLine(String s){
try {
fos.write(s.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Ich habe es kaum kommentiert - mit Absicht. Du sollst dabei schließlich auch was lernen.
Und wenn Du was nicht verstehst, schau es nach, z. B. im Tutorial unter www.javabuch.de
hehe ja danke für euren code. leider bringt der mir nicht sehr viel,denn ich will wie gesagt ein und die selbe datei editieren und nicht von einer datei lesen,das gelesene verarbeiten und in eine neue datei schreiben.
das würde irgendwann meine festplatte killen (weil es um sehr große datenmengen geht) und ich die datei mehrmals anfassen muss.
ums mal zu beschreiben.
ich schaue in die datei und suche mir eine variable (die in der datei steht) daraufhin gehe ich durch die komplette datei und suche weitere vorkommen dieser variable. kommt sie noch ein mal vor,wird sich komplett entfernt.
daraufhin wird die selbe prozedur wieder durchgeführt,bis nichts mehr vereinfacht werden konnte.
wenn ich nun eine 2gb datei habe und diese jedes mal lesen,editieren,in eine neue datei speichern würde,würde das ewigkeiten dauern.
deshalb suche ich eine lösung,wie ich eine zeile nehmen,editieren und in die selbe datei wieder schreiben kann.
ich bin übrigens kein java neuling. habe auch schon komplexere projekte in java umgesetzt.
aber bei dieser datenverarbeitung komme ich einfach nicht weiter.
ich will einfach nur eine bestimmt zeile nehmen,editeren und genau in diese zeile wieder schreiben,ohne jedes mal
die komplette datei kopieren oder über der kompletten datei iterieren zu müssen.
Wenn Du ganze Zeilen auf die oben beschriebene Art löschen willst, ist RandomAccessFile der bessere Ansatz, weil Du hier den Filepointer zurück setzen kannst. Du müßtest dann den Pointer um die Länge der zu löschenden Zeile zurück setzen. Allerdings wird dann das Ende der Datei nicht automatisch mit Leerzeichen überschrieben, da müßtest Du Dir noch was einfallen lassen.
Ob das so richtig viel Spaß macht, weiß ich nicht. ???:L
hehe ja danke für euren code. leider bringt der mir nicht sehr viel,denn ich will wie gesagt ein und die selbe datei editieren und nicht von einer datei lesen,das gelesene verarbeiten und in eine neue datei schreiben.
das würde irgendwann meine festplatte killen (weil es um sehr große datenmengen geht) und ich die datei mehrmals anfassen muss.
Die Klasse File hat da eine Methode namens delete()..... :wink:
Von wie vielen Variabeln reden wir hier eigentlich? Wieviele Mehrfach-Einträge kommen denn in der Regel so vor?
Der von Dir beschriebene Ansatz klingt für mich sehr umständlich. Wäre es eine Option vorkommende Variablen in einer Collection zu speichern und bei wiederholtem Auftreten sich die Zeilennummer oder den Wert des Filepointers zu merken und dann beim einmaligen Schreiben die gemerkten Zeilen wegzulassen?
Ist nur so eine Idee, da ich ja den Aufbau der zu bearbeitenden Datei nicht kenne....
Der Vorschlag von SlaterB mit der Verwendung einer Datenbank hätte übrigens auch seine Vorteile.