我正在讀取一個10MB大小的文件,其中包含一些ID。我把它們讀成紅寶石列表。我擔心它可能會在將來導致內存問題,當文件中的id數量可能會增加時。有批量閱讀大文件的有效方法嗎?紅寶石 - 批量讀取文件
謝謝
我正在讀取一個10MB大小的文件,其中包含一些ID。我把它們讀成紅寶石列表。我擔心它可能會在將來導致內存問題,當文件中的id數量可能會增加時。有批量閱讀大文件的有效方法嗎?紅寶石 - 批量讀取文件
謝謝
沒有通用的方法。
1)你可以通過閱讀文件塊:
File.open('filename','r') do |f|
chunk = f.read(2048)
...
end
缺點:你可以錯過一個字符串,如果它會是塊之間,也就是你尋找「SOME_TEXT」,而是「SOME_」是最後5個字節第一2048字節的塊,並且「TEXT」是一個4個字節的第二組塊的
2)可以讀取文件中的行由行
File.open('filename','r') do |f|
line = f.gets
...
end
缺點:這樣它會是2x..5x比第一種方法
慢隨着Lazy Enumerators和each_slice,你可以得到兩全其美。您不需要擔心中間的切割線,並且可以批量迭代多行。 batch_size
可以自由選擇。
header_lines = 1
batch_size = 2000
File.open("big_file") do |file|
file.lazy.drop(header_lines).each_slice(batch_size) do |lines|
# do something with batch of lines
end
end
它可以被用於導入一個巨大的CSV文件導入數據庫:
require 'csv'
batch_size = 2000
File.open("big_data.csv") do |file|
headers = file.first
file.lazy.each_slice(batch_size) do |lines|
csv_rows = CSV.parse(lines.join, write_headers: true, headers: headers)
# do something with 2000 csv rows, e.g. bulk insert them into a database
end
end
我依稀記得這是我一直在尋找的答案。正確的方式來讀取文件! – 2017-01-02 21:45:28
它應該如何工作?使用「懶惰」的目的是什麼? – Ilya 2017-08-10 12:16:09
我做了大量數據的基準測試,內存使用情況與不使用'.lazy.each_slice'鏈一樣。 – Ilya 2017-08-10 12:17:28