zip_tricks tidak akan menerima pembaruan atau dukungan lebih lanjut, dan tidak akan dikelola lagi. Kisah zip_tricks berlanjut di zip_kit yang akan menerima pembaruan rutin dan mendukung semua fungsi zip_tricks (dan banyak lagi). Terima kasih telah menjadi bagian dari komunitas zip_tricks!
Mengizinkan streaming, keluaran file ZIP yang tidak dapat diputar ulang dari Ruby.
Awalnya ditulis dan sebagai penerus spiritual zipline dan sekarang dengan bangga memberdayakannya.
Memungkinkan Anda menulis arsip ZIP ke File, Socket, String, atau Array tanpa harus memundurkannya kapan pun. Dapat digunakan untuk membuat arsip ZIP yang sangat besar untuk segera dikirim ke klien, atau untuk menulis arsip ZIP besar tanpa inflasi memori.
zip_tricks saat ini menangani semua kebutuhan zip kami (jutaan file ZIP dihasilkan per hari), jadi kami cukup yakin bahwa zip_tricks kompatibel secara luas dengan sejumlah besar aplikasi pengguna akhir yang tidak mengarsipkan.
Dukungan sintaksis Ruby 2.1+ (argumen kata kunci dengan default) dan zlib yang berfungsi (semuanya juga tersedia untuk jRuby). jRuby mungkin mengalami masalah saat menggunakan metode pembaca karena argumen IO#seek
dibatasi pada ukuran 32 bit.
Cara termudah adalah dengan memasukkan modul ZipTricks::RailsStreaming
ke dalam pengontrol Anda.
class ZipsController < ActionController :: Base
include ZipTricks :: RailsStreaming
def download
zip_tricks_stream do | zip |
zip . write_deflated_file ( 'report1.csv' ) do | sink |
CSV ( sink ) do | csv_write |
csv_write << Person . column_names
Person . all . find_each do | person |
csv_write << person . attributes . values
end
end
end
zip . write_deflated_file ( 'report2.csv' ) do | sink |
...
end
end
end
end
Jika Anda menginginkan lebih banyak kemudahan, Anda juga dapat menggunakan zipline yang secara otomatis akan memproses dan mengalirkan lampiran (Carrierwave, Shrine, ActiveStorage) dan objek jarak jauh melalui HTTP.
Kasus penggunaan dasar adalah mengompresi dengan cepat. Beberapa data akan di-buffer oleh deflator Zlib, namun inflasi memori akan sangat dibatasi. Data akan ditulis ke tujuan pada interval yang cukup teratur. Kompresi deflasi akan bekerja paling baik untuk hal-hal seperti file teks.
out = my_tempfile # can also be a socket
ZipTricks :: Streamer . open ( out ) do | zip |
zip . write_stored_file ( 'mov.mp4.txt' ) do | sink |
File . open ( 'mov.mp4' , 'rb' ) { | source | IO . copy_stream ( source , sink ) }
end
zip . write_deflated_file ( 'long-novel.txt' ) do | sink |
File . open ( 'novel.txt' , 'rb' ) { | source | IO . copy_stream ( source , sink ) }
end
end
Sayangnya dengan pendekatan ini tidak mungkin menghitung ukuran file ZIP yang dihasilkan, karena Anda tidak tahu seberapa besar segmen data yang dikompresi.
Untuk "menarik" data dari ZipTricks Anda dapat membuat objek OutputEnumerator
yang akan menghasilkan potongan biner sepotong demi sepotong, dan menerapkan sejumlah buffering juga. Karena OutputEnumerator
ini merespons #each
dan menghasilkan String, ia juga dapat (dan harus!) digunakan sebagai badan respons Rack. Kembalikan ke server web Anda dan ZIP Anda akan dialirkan. Blok yang Anda berikan ke OutputEnumerator
hanya akan mulai dieksekusi setelah isi respons Anda mulai diulangi - ketika sebenarnya mengirim respons ke klien (kecuali Anda menggunakan server web Rack buffering, seperti Webrick).
body = ZipTricks :: Streamer . output_enum do | zip |
zip . write_stored_file ( 'mov.mp4' ) do | sink | # Those MPEG4 files do not compress that well
File . open ( 'mov.mp4' , 'rb' ) { | source | IO . copy_stream ( source , sink ) }
end
zip . write_deflated_file ( 'long-novel.txt' ) do | sink |
File . open ( 'novel.txt' , 'rb' ) { | source | IO . copy_stream ( source , sink ) }
end
end
[ 200 , { } , body ]
Gunakan SizeEstimator
untuk menghitung ukuran yang benar dari arsip yang dihasilkan.
# Precompute the Content-Length ahead of time
bytesize = ZipTricks :: SizeEstimator . estimate do | z |
z . add_stored_entry ( filename : 'myfile1.bin' , size : 9090821 )
z . add_stored_entry ( filename : 'myfile2.bin' , size : 458678 )
end
# Prepare the response body. The block will only be called when the response starts to be written.
zip_body = ZipTricks :: RackBody . new do | zip |
zip . add_stored_entry ( filename : "myfile1.bin" , size : 9090821 , crc32 : 12485 )
zip << read_file ( 'myfile1.bin' )
zip . add_stored_entry ( filename : "myfile2.bin" , size : 458678 , crc32 : 89568 )
zip << read_file ( 'myfile2.bin' )
end
[ 200 , { 'Content-Length' => bytesize . to_s } , zip_body ]
Anda tidak perlu "memberi makan" semua isi file yang Anda masukkan ke dalam arsip melalui objek Streamer. Jika tujuan penulisan untuk kasus penggunaan Anda adalah Socket
(misalnya, Anda menulis menggunakan Rack hijack) dan Anda mengetahui metadata file di awal (CRC32 dari file yang tidak dikompresi dan ukurannya), Anda dapat menulis langsung ke soket tersebut menggunakan beberapa teknik penulisan yang dipercepat, dan hanya gunakan Streamer untuk menulis metadata ZIP.
# io has to be an object that supports #<<
ZipTricks :: Streamer . open ( io ) do | zip |
# raw_file is written "as is" (STORED mode).
# Write the local file header first..
zip . add_stored_entry ( filename : "first-file.bin" , size : raw_file . size , crc32 : raw_file_crc32 )
# Adjust the ZIP offsets within the Streamer
zip . simulate_write ( my_temp_file . size )
# ...and then send the actual file contents bypassing the Streamer interface
io . sendfile ( my_temp_file )
end
Lihat direktori examples/
di root proyek. Ini akan memberi Anda gambaran bagus tentang berbagai kasus penggunaan yang didukung perpustakaan.
BlockCRC32
menghitung checksum CRC32 dari IO secara streaming. Ini sedikit lebih nyaman untuk tujuan ini daripada menggunakan fungsi perpustakaan Zlib mentah.
crc = ZipTricks :: StreamCRC32 . new
crc << next_chunk_of_data
...
crc . to_i # Returns the actual CRC32 value computed so far
...
# Append a known CRC32 value that has been computed previosuly
crc . append ( precomputed_crc32 , size_of_the_blob_computed_from )
Anda juga dapat menghitung CRC32 untuk seluruh objek IO jika merespons #eof?
:
crc = ZipTricks :: StreamCRC32 . from_io ( file ) # Returns an Integer
Perpustakaan berisi modul pembaca, mainkan untuk melihat apa yang mungkin. Ini bukan pembaca ZIP yang lengkap tetapi dirancang untuk tujuan tertentu (pembongkaran file ZIP yang disimpan secara paralel secara paralel), dan karena itu ia menjalankan fungsinya dengan cukup baik. Harap berhati-hati terhadap implikasi keamanan dari penggunaan pembaca ZIP yang belum diverifikasi secara formal (milik kami belum diverifikasi).
main
terbaru untuk memastikan fitur tersebut belum diterapkan atau bug belum diperbaiki.Hak Cipta (c) 2020 WeTransfer.
zip_tricks
didistribusikan di bawah ketentuan Lisensi Hipokrates Lihat LICENSE.txt untuk rincian lebih lanjut. Jika lisensi ini tidak dapat diterima untuk kasus penggunaan Anda, kami masih mempertahankan pohon versi 4.x yang tetap berada di bawah lisensi MIT, lihat https://rubygems.org/gems/zip_tricks/versions untuk informasi lebih lanjut. Perhatikan bahwa kami hanya mendukung beberapa pengoptimalan kinerja dan perbaikan bug penting, tetapi tidak mendukung fitur baru pada pohon tersebut.