README.md in zip_tricks-5.4.0 vs README.md in zip_tricks-5.5.0

- old
+ new

@@ -33,13 +33,13 @@ def download zip_tricks_stream do |zip| zip.write_deflated_file('report1.csv') do |sink| CSV(sink) do |csv_write| - csv << Person.column_names + csv_write << Person.column_names Person.all.find_each do |person| - csv << person.attributes.values + csv_write << person.attributes.values end end end zip.write_deflated_file('report2.csv') do |sink| ... @@ -73,16 +73,19 @@ Unfortunately with this approach it is impossible to compute the size of the ZIP file being output, since you do not know how large the compressed data segments are going to be. ## Send a ZIP from a Rack response -Create a `RackBody` object and give it's constructor a block that adds files. -The block will only be called when actually sending the response to the client +To "pull" data from ZipTricks you can create an `OutputEnumerator` object which will yield the binary chunks piece +by piece, and apply some amount of buffering as well. Since this `OutputEnumerator` responds to `#each` and yields +Strings it also can (and should!) be used as a Rack response body. Return it to your webserver and you will +have your ZIP streamed. The block that you give to the `OutputEnumerator` will only start executing once your +response body starts getting iterated over - when actually sending the response to the client (unless you are using a buffering Rack webserver, such as Webrick). ```ruby -body = ZipTricks::RackBody.new do | zip | +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) } @@ -125,14 +128,15 @@ 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) - # then send the actual file contents bypassing the Streamer interface + # 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) - # ...and then adjust the ZIP offsets within the Streamer - zip.simulate_write(my_temp_file.size) end ``` ## Other usage examples