2012-04-05 10 views
3

Lets sagen, dass ich eine bescheidene Größe Textdatei (~ 850KB, 10.000+ Linien)Ersetzen eine Zeile in einer Datei, ohne die gesamte Datei zu Umschreiben (in PHP)

Und ich möchte eine bestimmte Zeile (oder mehrere ersetzen) verteilt in der Datei.

Aktuelle Methoden hierfür sind das Neuschreiben der gesamten Datei. Die aktuelle Methode, die ich benutze, wird zeilenweise durch die gesamte Datei gelesen, in eine .tmp-Datei geschrieben, und wenn ich fertig bin, benenne ich() die tmp-Datei in die ursprüngliche Quelldatei um.

Es funktioniert, aber es ist langsam. Und natürlich, wenn die Datei wächst, werden auch die Ausführungszeiten zunehmen.

Gibt es einen anderen Weg (mit PHP), um die Arbeit zu erledigen, ohne die gesamte Datei jedes Mal neu schreiben zu müssen, wenn eine oder zwei Zeilen ersetzt oder entfernt werden müssen?

Dank! Ich schaute mich um und konnte keine Antwort auf Stackoverflow finden.

+2

Sie müssen die gesamte Datei loopen. http://stackoverflow.com/questions/235604/overwrite-line-in-file-with-php –

+0

So gibt es keinen anderen Weg von der Methode, die ich derzeit verwende? – Kovo

+1

nein, das liegt an der Sicherheit. Was ist, wenn die Linie zum Beispiel eine Linie lang ist? –

Antwort

3

Wenn der Austausch ist genau die gleiche Größe wie die ursprüngliche Linie, dann können Sie einfach fwrite() an dieser Stelle in der Datei und alles ist gut. Aber wenn es eine andere Länge hat (kürzer ODER länger), müssen Sie den Teil der Datei neu schreiben, die nach der Ersetzung kommt.

Es gibt keinen Weg um diese. Kürzere 'neue' Zeilen hinterlassen eine Lücke in der Datei und längere 'neue' Zeilen überschreiben den ersten Teil der nächsten Zeile.

Grundsätzlich fragen Sie, ob es möglich ist, ein Stück Holz in die Mitte eines anderen Bretts zu legen, ohne das ursprüngliche Brett herumbewegen zu müssen.

+0

Das war, wovor ich Angst hatte. Natürlich würde eine Datenbank dies lösen, aber in diesem speziellen Fall ist eine Datenbank oder SQLite nicht möglich. Vielen Dank! – Kovo

+2

Eigentlich sollten Sie in der Lage sein, den Offset immer zu der Änderung zu überspringen. Abgesehen davon ist das Blockkopieren mit PHP AFAIK nicht möglich, daher empfehle ich für den Rest der Datei, einen Puffer zu nehmen (statt Zeile für Zeile). Ich denke, dass das ['SPLFileObject'] (http://php.net/SPLFileObject) die Pufferung intern durchführt, während Sie Ihren zeilenweisen Zugriff auf die Datei gewähren, also ist dies möglicherweise das Beste, was Sie mit weniger Code erreichen können. – hakre

2

Sie können nicht, aufgrund der Art, wie Dateien in gemeinsamen Dateisystemen gespeichert werden. Eine Datei belegt immer einen oder mehrere "Blöcke" an Speicherplatz, auf denen Blöcke beispielsweise eine Größe von 4096 Byte haben. Eine Datei mit einem Datenbyte belegt immer noch einen ganzen Block (4096 Byte verfügbaren Speicherplatz), während eine Datei mit 4097 Byte zwei Blöcke belegt (8192 Byte).

Wenn Sie ein Byte aus einer Datei entfernen, entsteht innerhalb eines Blocks eine Lücke von einem Byte, die nicht auf der Festplatte gespeichert werden kann. Sie müssen alle anderen Bytes um ein Byte an den Anfang der Datei verschieben, was sich auf den aktuellen und alle folgenden Blöcke auswirkt.

Anders herum zeigt das Hinzufügen von Bytes in der Mitte eines Blocks das gleiche Problem: Sie haben ein oder mehrere Bytes, die nicht mehr in die 4096 Bytes passen, also müssen sie sich dorthin verschieben der nächste Block und so weiter, bis das Ende der Datei (und aller Blöcke) erreicht ist.

Die einzige Stelle, an der Sie nicht belegte Bytes in einem Block haben können, ist am Ende des letzten Blocks, der eine Datei bildet.

Verwandte Themen