it-swarm.com.de

Was sind die häufigsten Möglichkeiten, eine Datei in Ruby zu lesen?

Was sind die häufigsten Möglichkeiten, eine Datei in Ruby zu lesen?

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?

252
dsg
File.open("my/file/path", "r") do |f|
  f.each_line do |line|
    puts line
  end
end
# File is closed automatically at end of block

Es ist auch möglich, die Datei wie oben explizit zu schließen (übergeben Sie einen Block an open, um sie für Sie zu schließen):

f = File.open("my/file/path", "r")
f.each_line do |line|
  puts line
end
f.close
240
fl00r

Der einfachste Weg, wenn die Datei nicht zu lang ist, ist:

puts File.read(file_name)

Tatsächlich schließt IO.read oder File.read die Datei automatisch, sodass File.open nicht mit einem Block verwendet werden muss.

286
mckeed

Seien Sie vorsichtig beim "Slurping" von Dateien. Dann lesen Sie die gesamte Datei gleichzeitig in den Speicher. 

Das Problem ist, dass es nicht gut skaliert. Sie könnten Code mit einer Datei von angemessener Größe entwickeln und dann in der Produktion einsetzen und plötzlich feststellen, dass Sie versuchen, Dateien in Gigabyte zu lesen, und Ihr Host friert ein, während er versucht, Speicher zu lesen und zuzuordnen. 

Line-by-Line-E/A ist sehr schnell und fast immer so effektiv wie das Slurping. Es ist eigentlich überraschend schnell.

Ich benutze gerne:

IO.foreach("testfile") {|x| print "GOT ", x }

oder

File.foreach('testfile') {|x| print "GOT", x }

Datei erbt von IO, und foreach befindet sich in IO, daher können Sie beide verwenden.

Ich habe einige Benchmarks, die die Auswirkungen des Versuchs zeigen, große Dateien über read vs. zeilenweise E/A an " " zu lesen. Warum ist "slurping" eine Datei keine bewährte Methode? ".

206
the Tin Man

Sie können die Datei auf einmal lesen:

content = File.readlines 'file.txt'
content.each_with_index{|line, i| puts "#{i+1}: #{line}"}

Wenn die Datei groß ist oder groß sein kann, ist es normalerweise besser, sie zeilenweise zu verarbeiten:

File.foreach( 'file.txt' ) do |line|
  puts line
end

Manchmal möchten Sie jedoch auf das Dateihandle zugreifen oder die Lesevorgänge selbst steuern:

File.open( 'file.txt' ) do |f|
  loop do
    break if not line = f.gets
    puts "#{f.lineno}: #{line}"
  end
end

Im Falle von Binärdateien können Sie wie folgt ein Null-Trennzeichen und eine Blockgröße angeben:

File.open('file.bin', 'rb') do |f|
  loop do
    break if not buf = f.gets(nil, 80)
    puts buf.unpack('H*')
  end
end

Schließlich können Sie dies auch ohne Blockierung tun, wenn Sie beispielsweise mehrere Dateien gleichzeitig bearbeiten. In diesem Fall muss die Datei explizit geschlossen werden (gemäß Kommentar von @antinome verbessert):

begin
  f = File.open 'file.txt'
  while line = f.gets
    puts line
  end
ensure
  f.close
end

Referenzen: Datei-API und die IO -API .

65
Victor Klos

Eine einfache Methode ist die Verwendung von readlines :

my_array = IO.readlines('filename.txt')

Jede Zeile in der Eingabedatei ist ein Eintrag im Array. Die Methode behandelt das Öffnen und Schließen der Datei für Sie.

23
bta
file_content = File.read('filename with extension');
puts file_content;

http://www.Ruby-doc.org/core-1.9.3/IO.html#method-c-read

16
Kumar Immanuel

Ich mache das normalerweise:

open(path_in_string, &:read)

Dadurch erhalten Sie den gesamten Text als String-Objekt. Es funktioniert nur unter Ruby 1.9.

9
sawa

rückgabe der letzten n Zeilen aus Ihrer Datei.log oder

path = File.join(Rails.root, 'your_folder','your_file.log')

last_100_lines = `tail -n 100 #{path}`
4
Alex Danko
content = `cat file`

Ich denke, dass diese Methode die "ungewöhnlichste" ist. Vielleicht ist es etwas schwierig, aber es funktioniert, wenn cat installiert ist.

0
helloqiu

Eine noch effizientere Methode ist das Streaming, indem der Kernel des Betriebssystems aufgefordert wird, eine Datei zu öffnen und dann Bit für Bit Bytes daraus zu lesen. Beim Lesen einer Datei pro Zeile in Ruby werden die Daten 512 Byte lang aus der Datei entnommen und danach in "Zeilen" aufgeteilt.

Durch das Puffern des Dateiinhalts wird die Anzahl der E/A-Aufrufe reduziert, während die Datei in logische Blöcke unterteilt wird.

Beispiel:

Fügen Sie diese Klasse als Serviceobjekt Ihrer App hinzu:

class MyIO
  def initialize(filename)
    fd = IO.sysopen(filename)
    @io = IO.new(fd)
    @buffer = ""
  end

  def each(&block)
    @buffer << @io.sysread(512) until @buffer.include?($/)

    line, @buffer = @buffer.split($/, 2)

    block.call(line)
    each(&block)
  rescue EOFError
    @io.close
 end
end

Rufen Sie es auf und übergeben Sie der :each-Methode einen Block:

filename = './somewhere/large-file-4gb.txt'
MyIO.new(filename).each{|x| puts x }

Lesen Sie hier in diesem ausführlichen Beitrag darüber:

Ruby Magic Slurping & Streaming-Dateien von AppSignal

0