Ho problemi dove devo scaricare, decomprimere e quindi elaborare riga per riga un file CSV molto grande. Penso che sia utile per dare un'idea quanto sia grande il file è:Stream e decomprimere file csv di grandi dimensioni con ruby
- big_file.zip ~ 700MB
- big_file.csv ~ 23GB
Ecco alcune cose che vorrei per accadere:
- non c'è bisogno di scaricare l'intero file prima di decomprimere
- non dover decomprimere tutto il file prima di parsing linee csv 0.123.
- Non utilizzare su molto di memoria/disco mentre si fa tutto questo
Non so se è possibile o no. Ecco cosa stavo pensando:
require 'open-uri'
require 'rubyzip'
require 'csv'
open('http://foo.bar/big_file.zip') do |zipped|
Zip::InputStream.open(zipped) do |unzipped|
sleep 10 until entry = unzipped.get_next_entry && entry.name == 'big_file.csv'
CSV.foreach(unzipped) do |row|
# process the row, maybe write out to STDOUT or some file
end
end
end
Ecco i problemi che so di:
open-uri
legge tutta risposta e lo salva in unTempfile
, che non va bene con un file di queste dimensioni. Probabilmente avrei bisogno di usareNet::HTTP
direttamente, ma non sono sicuro di come farlo e ottenere ancora unIO
.- Non so quanto velocemente sarà il download o se il
Zip::InputStream
funziona come ho mostrato. È possibile decomprimere alcuni file quando non è ancora tutto? - Il
CSV.foreach
funziona con RubyzipInputStream
? Si comporta abbastanza comeFile
che sarà in grado di analizzare le righe? Sarà fuori di testa se vuole leggere ma il buffer è vuoto?
Non so se questo è l'approccio giusto. Forse una soluzione EventMachine sarebbe meglio (anche se non ho mai usato EventMachine prima, ma se funziona meglio per qualcosa di simile, sono tutto a posto).
Non penso che lo streaming dello zip funzionerà a causa della struttura dei file zip. Potrebbe forse fare qualcosa come 'funzip' se c'era solo un file nello zip (o quello che volevo era il primo) ma non è così. – ZombieDev