Was sind die gängigen Methoden zum Lesen einer Datei in Ruby?
Hier ist zum Beispiel eine Methode:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Ich weiß, dass Ruby extrem flexibel ist. Was sind die Vor- und Nachteile jedes Ansatzes?
Antworten:
Es ist auch möglich, die Datei nach wie oben explizit zu schließen (übergeben Sie einen Block, um
open
sie für Sie zu schließen):quelle
foreach
anstelle des Blocksopen
und verzichten Sie daraufeach_line
.f.each { |line| ... }
undf.each_line { |line| ... }
scheinen das gleiche Verhalten zu haben (zumindest in Ruby 2.0.0).Der einfachste Weg, wenn die Datei nicht zu lang ist, ist:
In der Tat
IO.read
oderFile.read
schließen Sie die Datei automatisch, sodass Sie sie nichtFile.open
mit einem Block verwenden müssen.quelle
IO.read
oderFile.read
schließen Sie die Datei auch automatisch, obwohl Ihr Wortlaut so klingt, als ob dies nicht der Fall wäre.Seien Sie vorsichtig beim "Schlürfen" von Dateien. Dann lesen Sie die gesamte Datei auf einmal in den Speicher.
Das Problem ist, dass es nicht gut skaliert. Möglicherweise entwickeln Sie Code mit einer Datei mit angemessener Größe, stellen ihn dann in Produktion und stellen plötzlich fest, dass Sie versuchen, Dateien mit einer Größe von Gigabyte zu lesen, und Ihr Host friert ein, während er versucht, Speicher zu lesen und zuzuweisen.
Zeile für Zeile ist die E / A sehr schnell und fast immer so effektiv wie das Schlürfen. Es ist eigentlich überraschend schnell.
Ich benutze gerne:
oder
Die Datei erbt von IO und
foreach
befindet sich in IO, sodass Sie beide verwenden können.Ich habe einige Benchmarks, die zeigen, wie sich der Versuch auswirkt, große Dateien über
read
zeilenweise E / A zu lesen, unter " Warum ist das" Schlürfen "einer Datei keine gute Vorgehensweise? ".quelle
Sie können die Datei auf einmal lesen:
Wenn die Datei groß ist oder groß sein kann, ist es normalerweise besser, sie zeilenweise zu verarbeiten:
Manchmal möchten Sie jedoch auf das Dateihandle zugreifen oder die Lesevorgänge selbst steuern:
Bei Binärdateien können Sie ein Nulltrennzeichen und eine Blockgröße wie folgt angeben:
Schließlich können Sie es ohne Block tun, beispielsweise wenn Sie mehrere Dateien gleichzeitig verarbeiten. In diesem Fall muss die Datei explizit geschlossen werden (verbessert gemäß Kommentar von @antinome):
Referenzen: Datei-API und E / A-API .
quelle
for_each
in Datei oder E / A. Verwenden Sieforeach
stattdessen.while
anstelle vonloop
und zu verwenden,ensure
um sicherzustellen, dass die Datei geschlossen wird, auch wenn eine Ausnahme ausgelöst wird. So (Semikolons durch Zeilenumbrüche ersetzen) :begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
.Eine einfache Methode ist zu verwenden
readlines
:Jede Zeile in der Eingabedatei ist ein Eintrag im Array. Die Methode behandelt das Öffnen und Schließen der Datei für Sie.
quelle
read
oder jeder anderen Variante wird dadurch die gesamte Datei in den Speicher gezogen, was zu großen Problemen führen kann, wenn die Datei größer als der verfügbare Speicher ist. Da es sich um ein Array handelt, muss Ruby das Array erstellen, was den Prozess zusätzlich verlangsamt.http://www.ruby-doc.org/core-1.9.3/IO.html#method-c-read
quelle
Normalerweise mache ich das:
Dadurch erhalten Sie den gesamten Text als Zeichenfolgenobjekt. Es funktioniert nur unter Ruby 1.9.
quelle
Geben Sie die letzten n Zeilen aus your_file.log oder .txt zurück
quelle
Eine noch effizientere Methode ist das Streaming, indem der Kernel des Betriebssystems aufgefordert wird, eine Datei zu öffnen und dann nach und nach Bytes daraus zu lesen. Beim Lesen einer Datei pro Zeile in Ruby werden Daten jeweils 512 Byte aus der Datei entnommen und danach in „Zeilen“ aufgeteilt.
Durch Puffern des Dateiinhalts wird die Anzahl der E / A-Aufrufe reduziert, während die Datei in logische Blöcke aufgeteilt wird.
Beispiel:
Fügen Sie diese Klasse Ihrer App als Serviceobjekt hinzu:
Rufen Sie es auf und übergeben Sie der
:each
Methode einen Block:Lesen Sie hier in diesem ausführlichen Beitrag darüber:
Ruby Magic Slurping & Streaming-Dateien von AppSignal
quelle
Ich denke, diese Methode ist die "ungewöhnlichste". Vielleicht ist es etwas schwierig, aber es funktioniert, wenn
cat
es installiert ist.quelle
content = File.read(filename)