Jakie są typowe sposoby odczytu pliku w Rubim?
Na przykład, oto jedna metoda:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
Wiem, że Ruby jest niezwykle elastyczna. Jakie są zalety / wady każdego podejścia?
Odpowiedzi:
Możliwe jest również jawne zamknięcie pliku po jak wyżej (przekaż blok, aby
open
go zamknąć):źródło
foreach
zamiastopen
i zrezygnuj zeach_line
bloku.f.each { |line| ... }
if.each_line { |line| ... }
wydają się mieć takie samo zachowanie (przynajmniej w Ruby 2.0.0).Najłatwiejszym sposobem, jeśli plik nie jest zbyt długi, jest:
Rzeczywiście
IO.read
lubFile.read
automatycznie zamknij plik, więc nie ma potrzeby używaniaFile.open
z blokiem.źródło
IO.read
lubFile.read
też automatycznie zamknij plik, chociaż twoje sformułowania sprawiają, że brzmi on inaczej.Uważaj na pliki „slurping”. Wtedy od razu odczytujesz cały plik do pamięci.
Problem polega na tym, że nie skaluje się dobrze. Możesz opracowywać kod z plikiem o rozsądnych rozmiarach, a następnie wprowadzić go do produkcji i nagle odkryć, że próbujesz odczytać pliki mierzone w gigabajtach, a Twój host zawiesza się, gdy próbuje odczytać i przydzielić pamięć.
Line-by-I / O jest bardzo szybki i prawie zawsze tak samo skuteczny jak slurping. W rzeczywistości jest zaskakująco szybki.
Lubię używać:
lub
Plik dziedziczy z IO i
foreach
jest w IO, więc możesz użyć jednego z nich.Mam pewne testy porównawcze pokazujące wpływ próby odczytu dużych plików za pomocą operacji
read
we / wy wiersz po wierszu w sekcji „ Dlaczego„ zamazywanie ”pliku nie jest dobrą praktyką? ”.źródło
Możesz odczytać plik naraz:
Gdy plik jest duży lub może być duży, zwykle lepiej jest go przetwarzać wiersz po wierszu:
Czasami chcesz uzyskać dostęp do uchwytu pliku lub samodzielnie kontrolować odczyty:
W przypadku plików binarnych możesz podać separator zerowy i rozmiar bloku, na przykład:
Wreszcie możesz to zrobić bez bloku, na przykład podczas przetwarzania wielu plików jednocześnie. W takim przypadku plik musi zostać jawnie zamknięty (poprawiony zgodnie z komentarzem @antinome):
Odnośniki: File API i IO API .
źródło
for_each
w pliku lub we / wy. Użyjforeach
zamiast tego.while
zamiastloop
i użycie,ensure
aby upewnić się, że plik zostanie zamknięty, nawet jeśli zostanie zgłoszony wyjątek. Tak (zastąpienia średników z nowej linii)begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
.Jedną z prostych metod jest użycie
readlines
:Każda linia w pliku wejściowym będzie wpisem w tablicy. Ta metoda obsługuje otwieranie i zamykanie pliku.
źródło
read
dowolnego wariantu spowoduje to wciągnięcie całego pliku do pamięci, co może powodować poważne problemy, jeśli plik jest większy niż dostępna pamięć. Ponadto, ponieważ jest to tablica, Ruby musi ją utworzyć, co dodatkowo spowalnia proces.http://www.ruby-doc.org/core-1.9.3/IO.html#method-c-read
źródło
Zazwyczaj robię to:
To da ci cały tekst jako ciąg znaków. Działa tylko pod Ruby 1.9.
źródło
zwraca ostatnie n wierszy z twojego_pliku.log lub .txt
źródło
Jeszcze bardziej wydajnym sposobem jest przesyłanie strumieniowe, prosząc jądro systemu operacyjnego o otwarcie pliku, a następnie odczytanie z niego bajtów po kawałku. Podczas odczytywania pliku w wierszu w języku Ruby dane są pobierane z pliku 512 bajtów naraz i dzielone na „linie”.
Dzięki buforowaniu zawartości pliku zmniejsza się liczba wywołań We / Wy, dzieląc plik na logiczne części.
Przykład:
Dodaj tę klasę do swojej aplikacji jako obiekt usługi:
Zadzwoń i przekaż
:each
metodzie blok:Przeczytaj o tym tutaj w tym szczegółowym poście:
Ruby Magic Slurping & Streaming Files By AppSignal
źródło
Myślę, że ta metoda jest najbardziej „rzadka”. Może to trochę trudne, ale działa, jeśli
cat
jest zainstalowane.źródło
content = File.read(filename)