Edit (Ich habe den Titel angepasst): Ich verwende CSV.foreach, aber das beginnt in der ersten Zeile. Ich möchte beginnen, eine Datei an einer beliebigen Zeile zu lesen, ohne die Datei in den Speicher zu laden. CSV.foreach funktioniert gut zum Abrufen von Daten am Anfang einer Datei, aber nicht für Daten, die ich am Ende einer Datei benötige.Wählen Sie die Startzeile für CSV.foreach oder ähnliche Methode? Ich möchte keine Datei in den Speicher laden
This answer ist vergleichbar mit dem, was ich suche, aber es lädt die gesamte Datei in den Speicher; was ich nicht machen will.
Ich habe eine 10GB-Datei und die key
Spalte aufsteigend sortiert wird:
# example 10gb file rows
key,state,name
1,NY,Jessica
1,NY,Frank
1,NY,Matt
2,NM,Jesse
2,NM,Saul
2,NM,Walt
etc..
finde ich die Linie, die ich mit diesem Weg beginnen soll ...
file = File.expand_path('~/path/10gb_file.csv')
File.open(file, 'rb').each do |line|
if line[/^2,/]
puts "#{$.}: #{line}" # 5: 2,NM,Jesse
row_number = $. # 5
break
end
end
... und ich möchte row_number
nehmen und etwas zu tun, nicht aber die 10GB-Datei in den Speicher laden:
CSV.foreach(file, headers: true).drop(row_number) { |row| "..load data..." }
Zuletzt behandle ich es momentan wie das nächste Snippet; Es funktioniert einwandfrei, wenn die Zeilen zur Vorderseite der Datei zeigen, aber nicht, wenn sie sich in der Nähe des Endes befinden.
CSV.foreach(file, headers: true) do |row|
next if row['key'].to_i < row_number.to_i
break if row['key'].to_i > row_number.to_i
"..load data..."
end
Ich versuche CSV.foreach
zu verwenden, aber ich bin offen für Vorschläge.
- Verwenden
IO
oderFile
und lesen Sie die Datei Zeile für Zeile - Erhalten Sie die Kopfzeile und bauen die hash: Ein alternativer Ansatz ich überlege aber scheint nicht für Zahlen in Richtung der Mitte einer Datei effizient zu sein manuell
- Read the file from the bottom für Zahlen in der Nähe der max
key
Wert
Es gibt Möglichkeiten, auf eine Datei mit einem bestimmten Offset zuzugreifen. Siehe die Dokumentation von IO.read, IO.seek und et. al. ('File' ist ein' IO'). – Raffael
Erwägen Sie, Ihre Daten in einer Datenbank zu speichern. Diese Dinge sind wahnsinnig gut beim Zugriff auf Daten auf verschiedene Arten :) – Raffael
@Raffael Danke für die Vorschläge, ich werde in IO.read' und 'IO.seek' schauen. Ich habe darüber nachgedacht, die Daten auch in der Datenbank zu speichern, wollte aber sehen, ob ich das Laden einer CSV optimieren könnte, weil der Datensatz, den ich verwende, ziemlich häufig ersetzt wird. – dwyd