RandomAccessFile - Bytes vom Anfang der Datei löschen

Status
Nicht offen für weitere Antworten.
Hallo,
icxh suche eine Methode, mit der ich eine fest definierte Anzahl von Bytes (z.B. 80 bytes) vom Anfang einer Datei löschen kann. Diese wurden vorher hineingeschrieben und sollen nun wieder gelöscht werden.
Es sollen alle Bytes von 0-80 gelöscht werden. Gibt es hierzu eine Möglichkeit für RandomAccessFile?
Vielen Dank.
Andreas.
 
G

Guest

Gast
Nicht direkt bzw. am Anfang der Datei nicht.
Es geht nur durch's Umkopieren.
z.B.
Code:
RandomAccessFile file = new RandomAccessFile("datei.dat", "rw");
// Alle Bytes ab Position 80 an den Anfang der Datei umkopieren
file.getChannel().transferTo(80, file.length(), file.getChannel()); 
// Datei am Ende um 80 Byte verkürzen
file.setLength(file.length()-80);
Das dürfte ziemlich schnell sein.
Achtung. Es ist nicht getestet!
Prüfe, ob es so funktioniert. Fehler könnten auftauchen, wenn der Lesepuffer
größer ist, als der Schreibpuffer. Also, wenn der Lesezeiger den Schreibzeiger
überholt. Sollte aber nicht der Fall sein. :D

Gruß,
semi
 

thE_29

Top Contributor
Aber genau so mache ich meinen weg auch ;)

Nur ich öffne 2 RandomAccessFile Objekte (einmal nur r und einmal rw) und lese es auch raus und verkürze die Datei!
 
Vielen Dank für die bisherigen Antworten.
Ist denn die Methode mit 2 RandomAccessFile Objekten schneller? Was bringt Sie für Vorteile. Ich arbeit meist mit sehr großen Datei teilweise im zweistelligen GB Bereich. Wie verhält sich das mit dem umkopieren. Dauert das dann nicht ewig? Gibt es vielleicht noch eine andere Art Bytes an den Anfang einer Datei zu schreiben (Header) und nach späterem Auslesen diese wieder zu löschen? Vielen Dank. Andreas.
 

thE_29

Top Contributor
Unter Java gibts das nicht, mit C geht das ...


Ich habs mit 2 gemacht und auch mit byte buffer und mit changles so wie oben beschrieben!

Ich arbeite nur mit Files um die 500 MB und da gehts ruckzuck unter Linux..

Habe es ja nur mit 2 gemacht, weil ich net sicher war ob es mit 1 Objekt auch geht...

Probiers halt mal aus ;)
 
Also mit dem Löschen funktioniert das jetzt. Ich habe mal ein paar Byte im Editor an den Anfang geschrieben und mit der oben stehenden Lösung wieder gelöscht und das hat geklappt. Nun aber ein neues Problem )-:
Beim schreiben per RandomAccessFile in die Datei überschreibt mir die Funktion writeBytes den eigentlichen Inhalt der Datei. Ziel ist es 80byte Informationen an den Anfang einer Datei zu schreiben. Wie kann ich dies realisieren, ohne das der eigentliche Inhalt überschrieben wird. Es müsste also zunächst die Datei vergrößert werden, der Inhalt nach hinten kopiert und der Header an den Anfang geschrieben werden. Ideen??? Vielen Dank. Andreas.
 

thE_29

Top Contributor
Probier mal FileOutputstream da kann man append sagen (im Konstruktor)

Und dort den channel holen oder dgl (oder positionieren am Anfang) und dann am Anfang rein oder alles nach hinten verschieben..
 
Habs grade so probiert:

FileOutputStream file = new FileOutputStream(filename,false);
DataOutputStream out = new DataOutputStream(file);
out.writeBytes(Beschreibung);
out.flush();
out.close();

Wenn ich append auf true setze wird alles ans Ende der Datei geschrieben und wenn ich es auf false setze, dann steht nur der String"Beschreibung" in der alten Datei. Also noch keine Lösung. Bin für jede Hilfe dankbar.
 

thE_29

Top Contributor
Hier der Supercode von mir dazu :bae:

Code:
  public void storeAtBegin(String text) throws Exception
  {
    RandomAccessFile filow = new RandomAccessFile("C:\\test.txt","rw");
    BufferedReader br = new BufferedReader(
      new InputStreamReader(
        new FileInputStream("C:\\test.txt")));
    byte _text[] = text.getBytes();
    filow.skipBytes(_text.length);
    String lines[] = new String[2];
    while ( ( lines[0] = br.readLine() ) != null)
    {
      if(lines[1] != null)
      {
        StringBuffer strBuf = new StringBuffer(lines[1]);
        strBuf.append("\n"); //unter Linux isses glaube ich \n\r
        filow.write(strBuf.toString().getBytes());
      }
      lines[1] = lines[0];
    }
    if(lines[1] != null)
      filow.write(lines[1].getBytes());
    filow.seek(0); //auf anfang
    filow.write(_text); //jetzt noch den Text fürn Anfang wennst Zeilenumbruch willst, musst den mitübergeben
    br.close();
    filow.close();
  }


Achja, das ganze muss natürlich net zeilenweise gelesen werden, könntest du mit byte[] arrays genauso machen...

Zb byte buf[][] = new byte[2][1024]

Und dann via InputStreamReader mit read hinein und auch immer 2 Blöcke lesen...

Glaube mit byte isses schneller!
 
Vielen Dank für den Code. Wenn ich diesen allerdings ausführe, läuft das Programm ohne Fehler allerdings auch ohne Ende. Die Datei wird immer größer und der Inhalt ist völlig durcheinander. Haut also noch nicht ganz hin. Gibt es denn nicht ne einfacherer Variante. Bin nicht so der Java Gott und versteh auch nicht alles was da in dem Code gemacht wird. Vielleicht noch jemand nen Tip für mich? Danke. Andreas.
 
Es ist eine XML Datei mit Größe 99KB und ich schreibe einen 80 byte großen String rein. wenn ich das programm ein paar sekunden laufen lasse, ist die datei schon über 60 MB.
 
Habs nochmal probiert. Das einzige was das Programm macht, ist den Inhalt in einer Endlosschleife immer wieder in die Datei zu schreiben. Der String wird nicht reingeschrieben.
 

thE_29

Top Contributor
Mhm..

Habs jetzt mit ner 126KB großen XML Datei probiert und habe

"Text am Anfang\n" in die Methode übergeben.

Geht ganz normal..

Wie rufst du die Datei auf?
 
try {
storeAtBegin("TextamAnfang\n");
} catch (Exception e) {
e.printStackTrace();
}
dies rufe ich in meiner main auf.
eine test.txt datei mit dem inhalt "hallo" ergab das ergebnis, dass die datei immer größer wurde und tausende male hallo drin stand.
 

thE_29

Top Contributor
kann aber net sein....

weil die schleife abbrechen müsste...

Hast du nen Fehler beim kopieren gemacht??

Oder hast du unendlich leerzeilen am Ende?!


Weil die Schleife liest 1 Zeile ein und speichert diese, liest die nächste ein. Wenn nur 1 Zeile drinnen steht, müsste er also jetzt aufhören!

Daher, kann das bei 1er Zeile niemals ne endlosloop machen!
 

Leroy42

Top Contributor
thE_29 hat gesagt.:
Unter Java gibts das nicht, mit C geht das ...
:shock:
Wie bitte, soll denn das mit C möglich sein. C benutzt doch de facto
das was Java unter RandomAccess-File versteht.

Bei den heutigen Dateisystem in allen üblichen Betriebssystemen
kann es nun mal nicht gehen, einfach einen Teil am Anfang einer Datei
zu löschen. Ich glaube, bin mir aber nicht sicher, daß das mal in einem BS
(VMS!?) von IBM möglich war, indem einfach nur der Zeiger auf den Anfang
einer Datei verschoben wurde; aber das geht natürlich nur, wenn das BS
soetwas unterstützt.
 
Also wenn ich nur eine Zeile habe in der test.txt geht es wirklich. Allerdings habe ich es mit zwei anderen Dateien getestet und da war das Ergebniss wieder fehlerhaft. Wenn kein sauberes Zeilenende existiert, funktioniert der Code nicht. Es muss also eine andere Lösung gefunden werden. Das was Leroy42 gesagt hat ist richtig und leuchtet auch ein. Aber durch umkopieren innerhalb der Datei nach weiter hinten und anschliessendes Schreiben an den Dateianfang müsste das doch zu realisieren sein. Oder?
 

thE_29

Top Contributor
Was glaubst du was mein Code eigentlich macht ^^

Das Problem ist, das anscheinend bei dir ein endlosloop erzeugt wird..

Warum auch immer....
 
Ja genau das habe ich doch eben geschrieben. Mit einer 1 Zeilen Textdatei geht das wudnerbar.Aber es muss mit allen Dateien funktionieren. Auch Binärdateien und Zip Archive und und und. Es muss also absolut zuverlässig arbeiten. Und bei drei getesteten Dateien zwei Fehlerhaft ist nunmal nicht ausreichend. Ist ja nicht bös gemeint aber es funktioniert so eben nicht.
 

thE_29

Top Contributor
@Leoroy42: such mal fread, fwrite, fsetpos

Mit den 3 Befehlen kann man das super machen ...

Habe ja niemals gesagt das es Standardmethoden gibt..
 

Leroy42

Top Contributor
thE_29 hat gesagt.:
@Leoroy42: such mal fread, fwrite, fsetpos

Aber auch mit diesen Funktionen muß kopiert werden. Ein einfaches
"Abschneiden" der ersten Bytes geht unter keinem heutigen BS.

Vielleicht habe ich dein Zitat aber auch aus dem Kontext gerissen
und dich falsch verstanden.

Dann sorry!
 

thE_29

Top Contributor
Macht nix ;)

Kann sein das man es auffasst das es mit 1em Befehl geht ;)

Geht aber net :)

Code:
  public void storeAtBegin2(String text) throws Exception
  {
    FileInputStream in = new FileInputStream("C:\\ad_block.xml");
    RandomAccessFile out = new RandomAccessFile("C:\\ad_block.xml","rw");    
    byte _text[] = text.getBytes();
    out.skipBytes(_text.length);
    byte buf[][] = new byte[2][1024];
    int x[] = new int[2];
    
    while ( ( x[0] = in.read(buf[0],0,1024)) != -1 )
    {
      if(buf[1] != null) //nur wenn es nicht null ist => ab 2ten Durchlauf
        out.write(buf[1],0,x[1]);

      x[1] = x[0]; //wieviel bytes geschrieben werden müssen
      System.arraycopy(buf[0],0,buf[1],0,1024); //kopiert es rüber
    }
    if(buf[1] != null)
      out.write(buf[1],0,x[1]);
    out.seek(0); //auf den anfang setzen
    out.write(_text);
    in.close();
    out.close();
  }

Probier das mal aus!
 
So. Nun hab ich das Schreiben und das Löschen des Headers mit eurer Hilfe hinbekommen. Vielen Dank. Ich habe das ganze an einem XML File getestet. Das Problem liegt nun darin, dass die Datei vorher und nachher eine unterschiedliche Dateigröße haben. Kann das an dem hin und her kopieren innerhalb der datei liegen? Die Dateigröße war vorher 100.929 Bytes und danach 102.675 Bytes. Ich habe mir die Datei mit dem Editor angeschaut und der Header wurde ordentlich entfernt. Irgendetwas muss sich innerhalb der Datei verändert haben. Woran kann das liegen? Vielen Dank. Andreas.
 
Danke für den Link und das Programm. Ich habe beide XML Files eingelesen und das Ergebniss war schon etwas überaschend. Es wurde kein Unterschied gefunden. )-; Könnte es eventuell daran liegen, dass ich wenn ich die Original Datei mit dem Editor öffne der Text hintereinander mit Trennzeichen (kleines Viereck) dargestellt wird und wenn ich die veränderte Datei öffne diese schön strukturiert als XML Struktur mit Leerzeilen und so weiter dargestellt wird?
 

André Uhres

Top Contributor
In ExamDiff kannst du unter View|Options einstellen ob er Leerzeilen usw. ignorieren soll.
Vielleicht hilft das weiter.
 
Also ich habe die Einstellungen unter ExamDiff vorgenommen wie du vorgeschlagen hast. Das Ergebnis war, dass die File identisch sind und keine Unterschiede im Inhalt aufweisen. Allerdings weißen Sie Unterschiede in Ihrer Größe und Ihrer CHecksumme auf. Und das darf nicht sein. Gibt es nicht eine Andere Methode das Propblem zu lösen? Es sollen eine gewisse Anzahl von Bytes an den Anfang eine X beliebigen Datei geschrieben werden. Diese sollen später ausgelesen und wieder gelöscht werden, so dass die Datei wieder der Originaldatei entspricht. Vielen Dank. Andreas.
 

Leroy42

Top Contributor
AndreasMenzel hat gesagt.:
...der Text hintereinander mit Trennzeichen (kleines Viereck) dargestellt wird...

Das hört sich doch stark noch Zeilenseparator-Problem an :wink:

Wenn nur das Unix'sche LF (ASCII-10) statt des WinDoof'schen CR LF (ASCII-13 ASCII-10)
in einer Datei stehen, erkennen dies einfache Editoren (Notepad, ...) nicht als Zeilenende an.

Schick doch am besten die vollständige Source der Routine, die du jetzt benutzst
 
Code:
public void writeBytes(String Dateiname,String Beschreibung) throws Exception{

	  			RandomAccessFile ausgabedatei = null;
                
//==========================================================================	  			
	            try {
	                Beschreibung = Beschreibung + "\n";
	            	ausgabedatei = new RandomAccessFile(Dateiname, "rw");
	            	String Headerlaenge = Beschreibung.substring(0,4);
	            	int headerlength = new java.lang.Integer( Headerlaenge );
	            	long filelength = ausgabedatei.length();
	                ausgabedatei.seek(0);
	                if (ausgabedatei != null) {
	                	System.out.println("ByteWriter schreibt die Beschreibung in die Datei: " + Dateiname + "\n");
	           	     FileInputStream in = new FileInputStream(Dateiname); 
	        	     byte _text[] = Beschreibung.getBytes(); 
	        	     ausgabedatei.skipBytes(_text.length); 
	        	     byte buf[][] = new byte[2][1024]; 
	        	     int x[] = new int[2]; 
	        	     
	        	     while ( ( x[0] = in.read(buf[0],0,1024)) != -1 ) 
	        	     { 
	        	       if(buf[1] != null) //nur wenn es nicht null ist => ab 2ten Durchlauf 
	        	    	   ausgabedatei.write(buf[1],0,x[1]); 

	        	       x[1] = x[0]; //wieviel bytes geschrieben werden müssen 
	        	       System.arraycopy(buf[0],0,buf[1],0,1024); //kopiert es rüber 
	        	     } 
	        	     if(buf[1] != null) 
	        	    	 ausgabedatei.write(buf[1],0,x[1]); 
	        	     ausgabedatei.seek(0); //auf den anfang setzen 
	        	     ausgabedatei.write(_text); 
	        	     System.out.println("Die Datei: " + Dateiname + " hat " + ausgabedatei.length() + " Bytes...");
	        	     in.close(); 
	        	     ausgabedatei.close(); 
	                }
	            }
	            catch(Exception e) {
	                e.printStackTrace();
	            }
                
//==========================================================================
                    if (ausgabedatei != null) {
                        System.out.println("Die Datei: " + Dateiname + " hat nun " + ausgabedatei.length() + " Bytes..." + "\n" );
                        System.out.println("=======" );
                        ausgabedatei.close();
                    }
//==========================================================================	   }







public void deleteBytes(String Dateiname) throws Exception{

			RandomAccessFile ausgabedatei = null;
			String Beschreibung = null;
  			try {
                ausgabedatei = new RandomAccessFile(Dateiname, "rw");
                File filename = new File(Dateiname);
            	Beschreibung = ausgabedatei.readLine();
            	String Headerlaenge = Beschreibung.substring(0,4);
            	int headerlength = new java.lang.Integer( Headerlaenge );  
            	String Headertyp = Beschreibung.substring(4,9);
            	int headertyp = new java.lang.Integer( Headertyp ); 

            	System.out.println("ByteDeleter löscht den " + headerlength + " byte " + "Header der Datei: " + filename.getName() + "\n" );
                System.out.println("Die Datei: " + filename.getName() + " hat vor dem Löschen: " + ausgabedatei.length() + " Bytes...");

                ausgabedatei.seek(0);
//              Alle Bytes ab Position headerlength+1 (da Umbruch) an den Anfang der Datei umkopieren 
                ausgabedatei.getChannel().transferTo(headerlength+1, ausgabedatei.length(), ausgabedatei.getChannel()); 
//              Datei am Ende um 80 Byte verkürzen 
                ausgabedatei.setLength(ausgabedatei.length()-headerlength-1);

                System.out.println("Die Datei: " + filename.getName() + " hat nach dem Löschen: " + ausgabedatei.length() + " Bytes..." + "\n");
                ausgabedatei.close();
            }
            catch(Exception e) {
                e.printStackTrace();
            }
}
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S RandomAccessFile durch bytearrayinputstream ersetzen Allgemeine Java-Themen 4
A RandomAccessFile.read(byte[] b) Allgemeine Java-Themen 9
A RandomAccessFile - "insert" implementieren? Allgemeine Java-Themen 4
Iron Monkey RandomAccessFile - Bestimmte Filesize begrenzen Allgemeine Java-Themen 4
H RandomAccessFile - Zeile finden Allgemeine Java-Themen 5
C RandomAccessFile aus Jar Allgemeine Java-Themen 7
T Mit Applet per RandomAccessFile Datei öffnen Allgemeine Java-Themen 3
reibi RandomAccessFile Puffer schreiben Allgemeine Java-Themen 2
J RandomAccessFile readLine(); Allgemeine Java-Themen 5
R RandomAccessFile springt zum Ende Allgemeine Java-Themen 11
P Nochmal RandomAccessFile Allgemeine Java-Themen 6
N RandomAccessFile überschreibt Inhalt Allgemeine Java-Themen 3
B Probleme mit RandomAccessFile Allgemeine Java-Themen 3
R Knacken bei RandomAccessFile Allgemeine Java-Themen 5
K RandomAccessFile und readUTF/writeUTF Allgemeine Java-Themen 4
T RandomAccessFile im .jar Allgemeine Java-Themen 2
M RandomAccessFile Allgemeine Java-Themen 10
C BufferedReader/BufferedWriter schreibt nicht alle Bytes Allgemeine Java-Themen 2
V Input/Output Austausch von Bytes zwischen C# und Java Allgemeine Java-Themen 3
RalleYTN Input/Output Clip als ein Array von Bytes? Allgemeine Java-Themen 2
J Temperatur aus bytes auslesen. Allgemeine Java-Themen 13
Q Bytes verschwinden im CipherInputStream Allgemeine Java-Themen 1
L Methoden Methode gibt mir beim verschlüsseln mit RSA 0 bytes aus ? Allgemeine Java-Themen 1
J Bytes aus Socket lesen Allgemeine Java-Themen 9
Q Datentypen Short aus Bytes - Signed -> Unsigned? Allgemeine Java-Themen 9
C Datentypen int in bytes zerlegen und wieder zusammen setzen Allgemeine Java-Themen 13
K Hexadezimale Bytes Allgemeine Java-Themen 6
B bereits gelesene Bytes herausfinden Allgemeine Java-Themen 10
M FIFO Queue: bytes in, float/double/etc out Allgemeine Java-Themen 5
S String zu binary und zurück - Problem mit unsigned/signed bytes Allgemeine Java-Themen 2
TiME-SPLiNTER Von Unix, InputStreams und Null Bytes Allgemeine Java-Themen 2
K AES, Buffer und Bytes Allgemeine Java-Themen 2
S Bytes oder Hex-Werte zu Assembler Code? Allgemeine Java-Themen 6
L bytes nach int (little endian bitshift) Allgemeine Java-Themen 12
J Receive eines Hex-Bytes über COM-Port Allgemeine Java-Themen 4
G Zwei bytes vergleichen Allgemeine Java-Themen 2
M Bytes in Datei schreiben Allgemeine Java-Themen 10
T Spezielle Bytes in Datei schreiben Allgemeine Java-Themen 7
F Einlesen von Bytes Allgemeine Java-Themen 9
reibi Größe Array aus bytes Allgemeine Java-Themen 14
G RXTX verschicken einzelener Bytes Allgemeine Java-Themen 8
G WAV-Samples bearbeiten oder: 2 Bytes -> short -> float Allgemeine Java-Themen 5
T Größe eine Variablen in Bytes? Allgemeine Java-Themen 22
G Mehrere Bytes auf einmal einlesen Allgemeine Java-Themen 4
P int -> 4 bytes Allgemeine Java-Themen 11
R Menge an Bytes eines OutputStreams ermitteln. Allgemeine Java-Themen 6
R Wieviele Bytes gesendet Allgemeine Java-Themen 3
T Bestimmte bytes in einer Datei ersetzen? Allgemeine Java-Themen 4
D 16-Bit int --> 2* 8-Bit Bytes Allgemeine Java-Themen 17
H Objekte verbrauchen immer mindestens 16 Bytes Allgemeine Java-Themen 3
W Array größer als 65536 Bytes Allgemeine Java-Themen 7
C Code of a method longer than 65535 bytes Allgemeine Java-Themen 3
L 8 bytes von bestimmter position weg lesen? Allgemeine Java-Themen 11
D 2 Bytes in ein int convertieren Allgemeine Java-Themen 2
B Umwandeln von Bytes in float Zahl (DataInputStream) Allgemeine Java-Themen 3
G 0 Bytes bei temporäre Datei. Warum? Allgemeine Java-Themen 6
L Kursverlauf vorhersagen mit Deeplearning4j, aber komischer Knick am Anfang der Vorhersage Allgemeine Java-Themen 3
OnDemand String splitten (mit Anfang und Ende) Allgemeine Java-Themen 11
M String shuffeln, Anfang und Ende aber bleiben gleich Allgemeine Java-Themen 15
M Methoden Methode führt Ende vor dem Anfang aus Allgemeine Java-Themen 7
R Matcher - Pattern mit belibigem Anfang Allgemeine Java-Themen 2
M Von Paket zurück zu "Anfang" Allgemeine Java-Themen 5
R Copyright-Notiz am Anfang jeder Quellcode-Datei? Allgemeine Java-Themen 5
V Class Document seltsam leere Zeile am Anfang Allgemeine Java-Themen 8

Ähnliche Java Themen

Neue Themen


Oben