zip_tricks erhält keine weiteren Updates oder Support und wird nicht mehr gepflegt. Die Geschichte von zip_tricks wird in zip_kit fortgesetzt, das regelmäßig aktualisiert wird und alle Funktionen von zip_tricks (und mehr) unterstützt. Vielen Dank, dass Sie Teil der zip_tricks-Community sind!
Ermöglicht das Streamen der ZIP-Dateiausgabe von Ruby ohne Zurückspulen.
Ursprünglich als spiritueller Nachfolger von Zipline geschrieben und treibt es nun stolz unter der Haube voran.
Ermöglicht Ihnen, ein ZIP-Archiv in eine Datei, einen Socket, einen String oder ein Array zu schreiben, ohne es irgendwann zurückspulen zu müssen. Verwendbar zum Erstellen sehr großer ZIP-Archive zum sofortigen Versenden an Kunden oder zum Schreiben großer ZIP-Archive ohne Speichererweiterung.
zip_tricks erfüllt derzeit alle unsere Zip-Anforderungen (Millionen von pro Tag generierten ZIP-Dateien), daher sind wir ziemlich zuversichtlich, dass es weitgehend mit einer großen Anzahl von Endbenutzeranwendungen zur Entarchivierung kompatibel ist.
Ruby 2.1+-Syntaxunterstützung (Schlüsselwortargumente mit Standardwerten) und eine funktionierende Zlib (alles auch für jRuby verfügbar). Bei der Verwendung der Lesemethoden kann es bei jRuby zu Problemen kommen, da das Argument IO#seek
auf 32-Bit-Größen beschränkt ist.
Am einfachsten ist es, das ZipTricks::RailsStreaming
Modul in Ihren Controller einzubinden.
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
Wenn Sie mehr Komfort wünschen, können Sie auch Zipline verwenden, das Anhänge (Carrierwave, Shrine, ActiveStorage) und Remote-Objekte automatisch über HTTP verarbeitet und streamt.
Der grundlegende Anwendungsfall ist die Komprimierung im laufenden Betrieb. Einige Daten werden durch den Zlib-Deflater gepuffert, die Speichererweiterung wird jedoch sehr begrenzt sein. Die Daten werden in relativ regelmäßigen Abständen an das Ziel geschrieben. Die Deflate-Komprimierung funktioniert am besten für Dinge wie Textdateien.
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
Leider ist es bei diesem Ansatz nicht möglich, die Größe der ausgegebenen ZIP-Datei zu berechnen, da Sie nicht wissen, wie groß die komprimierten Datensegmente sein werden.
Um Daten aus ZipTricks zu „ziehen“, können Sie ein OutputEnumerator
Objekt erstellen, das die Binärblöcke Stück für Stück liefert und auch eine gewisse Pufferung anwendet. Da dieser OutputEnumerator
auf #each
antwortet und Strings liefert, kann (und sollte!) er auch als Rack-Antworttext verwendet werden. Senden Sie es an Ihren Webserver zurück und Sie werden Ihre ZIP-Datei streamen lassen. Der Block, den Sie dem OutputEnumerator
übergeben, beginnt erst mit der Ausführung, wenn Ihr Antworttext mit der Iteration beginnt – wenn die Antwort tatsächlich an den Client gesendet wird (es sei denn, Sie verwenden einen puffernden Rack-Webserver wie 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 ]
Verwenden Sie den SizeEstimator
, um die korrekte Größe des resultierenden Archivs zu berechnen.
# 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 ]
Sie müssen nicht den gesamten Inhalt der Dateien, die Sie im Archiv abgelegt haben, über das Streamer-Objekt „einspeisen“. Wenn das Schreibziel für Ihren Anwendungsfall ein Socket
ist (z. B. Sie schreiben mit Rack Hijack) und Sie die Metadaten der Datei im Voraus kennen (CRC32 der unkomprimierten Datei und die Größen), können Sie mit direkt in diesen Socket schreiben Verwenden Sie eine beschleunigte Schreibtechnik und verwenden Sie den Streamer nur zum Ausschreiben der ZIP-Metadaten.
# 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
Sehen Sie sich das Verzeichnis examples/
im Stammverzeichnis des Projekts an. Dadurch erhalten Sie einen guten Überblick über die verschiedenen Anwendungsfälle, die die Bibliothek unterstützt.
BlockCRC32
berechnet die CRC32-Prüfsumme eines IO im Streaming-Verfahren. Dies ist für diesen Zweck etwas praktischer als die Verwendung der rohen Zlib-Bibliotheksfunktionen.
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 )
Sie können den CRC32 auch für ein gesamtes IO-Objekt berechnen, wenn es auf #eof?
:
crc = ZipTricks :: StreamCRC32 . from_io ( file ) # Returns an Integer
Die Bibliothek enthält ein Lesemodul. Spielen Sie damit, um zu sehen, was möglich ist. Es ist kein vollständiger ZIP-Reader, wurde aber für einen bestimmten Zweck entwickelt (hochparalleles Entpacken von remote gespeicherten ZIP-Dateien) und erfüllt seine Funktion daher recht gut. Bitte beachten Sie die Sicherheitsauswirkungen der Verwendung von ZIP-Lesegeräten, die nicht offiziell verifiziert wurden (bei uns nicht).
main
an, um sicherzustellen, dass die Funktion nicht implementiert wurde oder der Fehler noch nicht behoben wurde.Copyright (c) 2020 WeTransfer.
zip_tricks
wird unter den Bedingungen der Hippocratic License vertrieben. Weitere Einzelheiten finden Sie in LICENSE.txt. Wenn diese Lizenz für Ihren Anwendungsfall nicht akzeptabel ist, pflegen wir weiterhin den 4.x-Versionsbaum, der weiterhin unter der MIT-Lizenz steht. Weitere Informationen finden Sie unter https://rubygems.org/gems/zip_tricks/versions. Beachten Sie, dass wir nur einige Leistungsoptimierungen und wichtige Bugfixes zurückportieren, nicht jedoch die neuen Funktionen in diesem Baum.