rubyzip 0.9.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +354 -0
  3. data/Rakefile +15 -104
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +212 -0
  6. data/lib/zip/compressor.rb +9 -0
  7. data/lib/zip/constants.rb +115 -0
  8. data/lib/zip/crypto/decrypted_io.rb +40 -0
  9. data/lib/zip/crypto/encryption.rb +11 -0
  10. data/lib/zip/crypto/null_encryption.rb +43 -0
  11. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  12. data/lib/zip/decompressor.rb +31 -0
  13. data/lib/zip/deflater.rb +34 -0
  14. data/lib/zip/dos_time.rb +53 -0
  15. data/lib/zip/entry.rb +719 -0
  16. data/lib/zip/entry_set.rb +88 -0
  17. data/lib/zip/errors.rb +19 -0
  18. data/lib/zip/extra_field/generic.rb +44 -0
  19. data/lib/zip/extra_field/ntfs.rb +94 -0
  20. data/lib/zip/extra_field/old_unix.rb +46 -0
  21. data/lib/zip/extra_field/universal_time.rb +77 -0
  22. data/lib/zip/extra_field/unix.rb +39 -0
  23. data/lib/zip/extra_field/zip64.rb +70 -0
  24. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  25. data/lib/zip/extra_field.rb +103 -0
  26. data/lib/zip/file.rb +468 -0
  27. data/lib/zip/filesystem.rb +643 -0
  28. data/lib/zip/inflater.rb +54 -0
  29. data/lib/zip/input_stream.rb +180 -0
  30. data/lib/zip/ioextras/abstract_input_stream.rb +122 -0
  31. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  32. data/lib/zip/ioextras.rb +21 -140
  33. data/lib/zip/null_compressor.rb +15 -0
  34. data/lib/zip/null_decompressor.rb +19 -0
  35. data/lib/zip/null_input_stream.rb +10 -0
  36. data/lib/zip/output_stream.rb +198 -0
  37. data/lib/zip/pass_thru_compressor.rb +23 -0
  38. data/lib/zip/pass_thru_decompressor.rb +31 -0
  39. data/lib/zip/streamable_directory.rb +15 -0
  40. data/lib/zip/streamable_stream.rb +52 -0
  41. data/lib/zip/version.rb +3 -0
  42. data/lib/zip.rb +72 -0
  43. data/samples/example.rb +44 -32
  44. data/samples/example_filesystem.rb +16 -19
  45. data/samples/example_recursive.rb +54 -0
  46. data/samples/gtk_ruby_zip.rb +84 -0
  47. data/samples/qtzip.rb +25 -34
  48. data/samples/write_simple.rb +10 -13
  49. data/samples/zipfind.rb +38 -45
  50. metadata +182 -91
  51. data/ChangeLog +0 -1504
  52. data/NEWS +0 -144
  53. data/README +0 -72
  54. data/install.rb +0 -22
  55. data/lib/download_quizzes.rb +0 -119
  56. data/lib/quiz1/t/solutions/Bill Guindon/solitaire.rb +0 -205
  57. data/lib/quiz1/t/solutions/Carlos/solitaire.rb +0 -111
  58. data/lib/quiz1/t/solutions/Dennis Ranke/solitaire.rb +0 -111
  59. data/lib/quiz1/t/solutions/Florian Gross/solitaire.rb +0 -301
  60. data/lib/quiz1/t/solutions/Glen M. Lewis/solitaire.rb +0 -268
  61. data/lib/quiz1/t/solutions/James Edward Gray II/solitaire.rb +0 -132
  62. data/lib/quiz1/t/solutions/Jamis Buck/bin/main.rb +0 -13
  63. data/lib/quiz1/t/solutions/Jamis Buck/lib/cipher.rb +0 -230
  64. data/lib/quiz1/t/solutions/Jamis Buck/lib/cli.rb +0 -24
  65. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_deck.rb +0 -30
  66. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_key-stream.rb +0 -19
  67. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_keying-algorithms.rb +0 -31
  68. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_solitaire-cipher.rb +0 -66
  69. data/lib/quiz1/t/solutions/Jamis Buck/test/tc_unkeyed-algorithm.rb +0 -17
  70. data/lib/quiz1/t/solutions/Jamis Buck/test/tests.rb +0 -2
  71. data/lib/quiz1/t/solutions/Jim Menard/solitaire_cypher.rb +0 -204
  72. data/lib/quiz1/t/solutions/Jim Menard/test.rb +0 -47
  73. data/lib/quiz1/t/solutions/Moses Hohman/cipher.rb +0 -97
  74. data/lib/quiz1/t/solutions/Moses Hohman/deck.rb +0 -140
  75. data/lib/quiz1/t/solutions/Moses Hohman/solitaire.rb +0 -14
  76. data/lib/quiz1/t/solutions/Moses Hohman/test_cipher.rb +0 -68
  77. data/lib/quiz1/t/solutions/Moses Hohman/test_deck.rb +0 -146
  78. data/lib/quiz1/t/solutions/Moses Hohman/test_util.rb +0 -38
  79. data/lib/quiz1/t/solutions/Moses Hohman/testsuite.rb +0 -5
  80. data/lib/quiz1/t/solutions/Moses Hohman/util.rb +0 -27
  81. data/lib/quiz1/t/solutions/Niklas Frykholm/solitaire.rb +0 -151
  82. data/lib/quiz1/t/solutions/Thomas Leitner/solitaire.rb +0 -198
  83. data/lib/zip/stdrubyext.rb +0 -111
  84. data/lib/zip/tempfile_bugfixed.rb +0 -195
  85. data/lib/zip/zip.rb +0 -1847
  86. data/lib/zip/zipfilesystem.rb +0 -609
  87. data/lib/zip/ziprequire.rb +0 -90
  88. data/samples/gtkRubyzip.rb +0 -86
  89. data/test/alltests.rb +0 -9
  90. data/test/data/file1.txt +0 -46
  91. data/test/data/file1.txt.deflatedData +0 -0
  92. data/test/data/file2.txt +0 -1504
  93. data/test/data/notzippedruby.rb +0 -7
  94. data/test/data/rubycode.zip +0 -0
  95. data/test/data/rubycode2.zip +0 -0
  96. data/test/data/testDirectory.bin +0 -0
  97. data/test/data/zipWithDirs.zip +0 -0
  98. data/test/gentestfiles.rb +0 -157
  99. data/test/ioextrastest.rb +0 -208
  100. data/test/stdrubyexttest.rb +0 -52
  101. data/test/zipfilesystemtest.rb +0 -831
  102. data/test/ziprequiretest.rb +0 -43
  103. data/test/ziptest.rb +0 -1599
@@ -0,0 +1,198 @@
1
+ module Zip
2
+ # ZipOutputStream is the basic class for writing zip files. It is
3
+ # possible to create a ZipOutputStream object directly, passing
4
+ # the zip file name to the constructor, but more often than not
5
+ # the ZipOutputStream will be obtained from a ZipFile (perhaps using the
6
+ # ZipFileSystem interface) object for a particular entry in the zip
7
+ # archive.
8
+ #
9
+ # A ZipOutputStream inherits IOExtras::AbstractOutputStream in order
10
+ # to provide an IO-like interface for writing to a single zip
11
+ # entry. Beyond methods for mimicking an IO-object it contains
12
+ # the method put_next_entry that closes the current entry
13
+ # and creates a new.
14
+ #
15
+ # Please refer to ZipInputStream for example code.
16
+ #
17
+ # java.util.zip.ZipOutputStream is the original inspiration for this
18
+ # class.
19
+
20
+ class OutputStream
21
+ include ::Zip::IOExtras::AbstractOutputStream
22
+
23
+ attr_accessor :comment
24
+
25
+ # Opens the indicated zip file. If a file with that name already
26
+ # exists it will be overwritten.
27
+ def initialize(file_name, stream = false, encrypter = nil)
28
+ super()
29
+ @file_name = file_name
30
+ @output_stream = if stream
31
+ iostream = @file_name.dup
32
+ iostream.reopen(@file_name)
33
+ iostream.rewind
34
+ iostream
35
+ else
36
+ ::File.new(@file_name, 'wb')
37
+ end
38
+ @entry_set = ::Zip::EntrySet.new
39
+ @compressor = ::Zip::NullCompressor.instance
40
+ @encrypter = encrypter || ::Zip::NullEncrypter.new
41
+ @closed = false
42
+ @current_entry = nil
43
+ @comment = nil
44
+ end
45
+
46
+ # Same as #initialize but if a block is passed the opened
47
+ # stream is passed to the block and closed when the block
48
+ # returns.
49
+ class << self
50
+ def open(file_name, encrypter = nil)
51
+ return new(file_name) unless block_given?
52
+
53
+ zos = new(file_name, false, encrypter)
54
+ yield zos
55
+ ensure
56
+ zos.close if zos
57
+ end
58
+
59
+ # Same as #open but writes to a filestream instead
60
+ def write_buffer(io = ::StringIO.new(''), encrypter = nil)
61
+ io.binmode if io.respond_to?(:binmode)
62
+ zos = new(io, true, encrypter)
63
+ yield zos
64
+ zos.close_buffer
65
+ end
66
+ end
67
+
68
+ # Closes the stream and writes the central directory to the zip file
69
+ def close
70
+ return if @closed
71
+
72
+ finalize_current_entry
73
+ update_local_headers
74
+ write_central_directory
75
+ @output_stream.close
76
+ @closed = true
77
+ end
78
+
79
+ # Closes the stream and writes the central directory to the zip file
80
+ def close_buffer
81
+ return @output_stream if @closed
82
+
83
+ finalize_current_entry
84
+ update_local_headers
85
+ write_central_directory
86
+ @closed = true
87
+ @output_stream
88
+ end
89
+
90
+ # Closes the current entry and opens a new for writing.
91
+ # +entry+ can be a ZipEntry object or a string.
92
+ def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
93
+ raise Error, 'zip stream is closed' if @closed
94
+
95
+ new_entry = if entry_name.kind_of?(Entry)
96
+ entry_name
97
+ else
98
+ Entry.new(@file_name, entry_name.to_s)
99
+ end
100
+ new_entry.comment = comment unless comment.nil?
101
+ unless extra.nil?
102
+ new_entry.extra = extra.kind_of?(ExtraField) ? extra : ExtraField.new(extra.to_s)
103
+ end
104
+ new_entry.compression_method = compression_method unless compression_method.nil?
105
+ init_next_entry(new_entry, level)
106
+ @current_entry = new_entry
107
+ end
108
+
109
+ def copy_raw_entry(entry)
110
+ entry = entry.dup
111
+ raise Error, 'zip stream is closed' if @closed
112
+ raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
113
+
114
+ finalize_current_entry
115
+ @entry_set << entry
116
+ src_pos = entry.local_header_offset
117
+ entry.write_local_entry(@output_stream)
118
+ @compressor = NullCompressor.instance
119
+ entry.get_raw_input_stream do |is|
120
+ is.seek(src_pos, IO::SEEK_SET)
121
+ ::Zip::Entry.read_local_entry(is)
122
+ IOExtras.copy_stream_n(@output_stream, is, entry.compressed_size)
123
+ end
124
+ @compressor = NullCompressor.instance
125
+ @current_entry = nil
126
+ end
127
+
128
+ private
129
+
130
+ def finalize_current_entry
131
+ return unless @current_entry
132
+
133
+ finish
134
+ @current_entry.compressed_size = @output_stream.tell - \
135
+ @current_entry.local_header_offset - \
136
+ @current_entry.calculate_local_header_size
137
+ @current_entry.size = @compressor.size
138
+ @current_entry.crc = @compressor.crc
139
+ @output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size)
140
+ @current_entry.gp_flags |= @encrypter.gp_flags
141
+ @current_entry = nil
142
+ @compressor = ::Zip::NullCompressor.instance
143
+ end
144
+
145
+ def init_next_entry(entry, level = Zip.default_compression)
146
+ finalize_current_entry
147
+ @entry_set << entry
148
+ entry.write_local_entry(@output_stream)
149
+ @encrypter.reset!
150
+ @output_stream << @encrypter.header(entry.mtime)
151
+ @compressor = get_compressor(entry, level)
152
+ end
153
+
154
+ def get_compressor(entry, level)
155
+ case entry.compression_method
156
+ when Entry::DEFLATED
157
+ ::Zip::Deflater.new(@output_stream, level, @encrypter)
158
+ when Entry::STORED
159
+ ::Zip::PassThruCompressor.new(@output_stream)
160
+ else
161
+ raise ::Zip::CompressionMethodError,
162
+ "Invalid compression method: '#{entry.compression_method}'"
163
+ end
164
+ end
165
+
166
+ def update_local_headers
167
+ pos = @output_stream.pos
168
+ @entry_set.each do |entry|
169
+ @output_stream.pos = entry.local_header_offset
170
+ entry.write_local_entry(@output_stream, true)
171
+ end
172
+ @output_stream.pos = pos
173
+ end
174
+
175
+ def write_central_directory
176
+ cdir = CentralDirectory.new(@entry_set, @comment)
177
+ cdir.write_to_stream(@output_stream)
178
+ end
179
+
180
+ protected
181
+
182
+ def finish
183
+ @compressor.finish
184
+ end
185
+
186
+ public
187
+
188
+ # Modeled after IO.<<
189
+ def <<(data)
190
+ @compressor << data
191
+ self
192
+ end
193
+ end
194
+ end
195
+
196
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
197
+ # rubyzip is free software; you can redistribute it and/or
198
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,23 @@
1
+ module Zip
2
+ class PassThruCompressor < Compressor #:nodoc:all
3
+ def initialize(output_stream)
4
+ super()
5
+ @output_stream = output_stream
6
+ @crc = Zlib.crc32
7
+ @size = 0
8
+ end
9
+
10
+ def <<(data)
11
+ val = data.to_s
12
+ @crc = Zlib.crc32(val, @crc)
13
+ @size += val.bytesize
14
+ @output_stream << val
15
+ end
16
+
17
+ attr_reader :size, :crc
18
+ end
19
+ end
20
+
21
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
22
+ # rubyzip is free software; you can redistribute it and/or
23
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,31 @@
1
+ module Zip
2
+ class PassThruDecompressor < Decompressor #:nodoc:all
3
+ def initialize(*args)
4
+ super
5
+ @read_so_far = 0
6
+ end
7
+
8
+ def read(length = nil, outbuf = '')
9
+ return (length.nil? || length.zero? ? '' : nil) if eof
10
+
11
+ if length.nil? || (@read_so_far + length) > decompressed_size
12
+ length = decompressed_size - @read_so_far
13
+ end
14
+
15
+ @read_so_far += length
16
+ input_stream.read(length, outbuf)
17
+ end
18
+
19
+ def eof
20
+ @read_so_far >= decompressed_size
21
+ end
22
+
23
+ alias eof? eof
24
+ end
25
+
26
+ ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
27
+ end
28
+
29
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
30
+ # rubyzip is free software; you can redistribute it and/or
31
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,15 @@
1
+ module Zip
2
+ class StreamableDirectory < Entry
3
+ def initialize(zipfile, entry, src_path = nil, permission = nil)
4
+ super(zipfile, entry)
5
+
6
+ @ftype = :directory
7
+ entry.get_extra_attributes_from_path(src_path) if src_path
8
+ @unix_perms = permission if permission
9
+ end
10
+ end
11
+ end
12
+
13
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
14
+ # rubyzip is free software; you can redistribute it and/or
15
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,52 @@
1
+ module Zip
2
+ class StreamableStream < DelegateClass(Entry) # :nodoc:all
3
+ def initialize(entry)
4
+ super(entry)
5
+ @temp_file = Tempfile.new(::File.basename(name))
6
+ @temp_file.binmode
7
+ end
8
+
9
+ def get_output_stream
10
+ if block_given?
11
+ begin
12
+ yield(@temp_file)
13
+ ensure
14
+ @temp_file.close
15
+ end
16
+ else
17
+ @temp_file
18
+ end
19
+ end
20
+
21
+ def get_input_stream
22
+ unless @temp_file.closed?
23
+ raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
24
+ end
25
+
26
+ @temp_file.open # reopens tempfile from top
27
+ @temp_file.binmode
28
+ if block_given?
29
+ begin
30
+ yield(@temp_file)
31
+ ensure
32
+ @temp_file.close
33
+ end
34
+ else
35
+ @temp_file
36
+ end
37
+ end
38
+
39
+ def write_to_zip_output_stream(output_stream)
40
+ output_stream.put_next_entry(self)
41
+ get_input_stream { |is| ::Zip::IOExtras.copy_stream(output_stream, is) }
42
+ end
43
+
44
+ def clean_up
45
+ @temp_file.unlink
46
+ end
47
+ end
48
+ end
49
+
50
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
51
+ # rubyzip is free software; you can redistribute it and/or
52
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,3 @@
1
+ module Zip
2
+ VERSION = '2.3.2'
3
+ end
data/lib/zip.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'English'
2
+ require 'delegate'
3
+ require 'singleton'
4
+ require 'tempfile'
5
+ require 'fileutils'
6
+ require 'stringio'
7
+ require 'zlib'
8
+ require 'zip/constants'
9
+ require 'zip/dos_time'
10
+ require 'zip/ioextras'
11
+ require 'rbconfig'
12
+ require 'zip/entry'
13
+ require 'zip/extra_field'
14
+ require 'zip/entry_set'
15
+ require 'zip/central_directory'
16
+ require 'zip/file'
17
+ require 'zip/input_stream'
18
+ require 'zip/output_stream'
19
+ require 'zip/decompressor'
20
+ require 'zip/compressor'
21
+ require 'zip/null_decompressor'
22
+ require 'zip/null_compressor'
23
+ require 'zip/null_input_stream'
24
+ require 'zip/pass_thru_compressor'
25
+ require 'zip/pass_thru_decompressor'
26
+ require 'zip/crypto/decrypted_io'
27
+ require 'zip/crypto/encryption'
28
+ require 'zip/crypto/null_encryption'
29
+ require 'zip/crypto/traditional_encryption'
30
+ require 'zip/inflater'
31
+ require 'zip/deflater'
32
+ require 'zip/streamable_stream'
33
+ require 'zip/streamable_directory'
34
+ require 'zip/errors'
35
+
36
+ module Zip
37
+ extend self
38
+ attr_accessor :unicode_names,
39
+ :on_exists_proc,
40
+ :continue_on_exists_proc,
41
+ :sort_entries,
42
+ :default_compression,
43
+ :write_zip64_support,
44
+ :warn_invalid_date,
45
+ :case_insensitive_match,
46
+ :force_entry_names_encoding,
47
+ :validate_entry_sizes
48
+
49
+ def reset!
50
+ @_ran_once = false
51
+ @unicode_names = false
52
+ @on_exists_proc = false
53
+ @continue_on_exists_proc = false
54
+ @sort_entries = false
55
+ @default_compression = ::Zlib::DEFAULT_COMPRESSION
56
+ @write_zip64_support = false
57
+ @warn_invalid_date = true
58
+ @case_insensitive_match = false
59
+ @validate_entry_sizes = true
60
+ end
61
+
62
+ def setup
63
+ yield self unless @_ran_once
64
+ @_ran_once = true
65
+ end
66
+
67
+ reset!
68
+ end
69
+
70
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
71
+ # rubyzip is free software; you can redistribute it and/or
72
+ # modify it under the terms of the ruby license.
data/samples/example.rb CHANGED
@@ -1,66 +1,78 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << "../lib"
4
- system("zip example.zip example.rb gtkRubyzip.rb")
3
+ $LOAD_PATH << '../lib'
4
+ system('zip example.zip example.rb gtk_ruby_zip.rb')
5
5
 
6
- require 'zip/zip'
6
+ require 'zip'
7
7
 
8
8
  ####### Using ZipInputStream alone: #######
9
9
 
10
- Zip::ZipInputStream.open("example.zip") {
11
- |zis|
10
+ Zip::InputStream.open('example.zip') do |zis|
12
11
  entry = zis.get_next_entry
13
12
  print "First line of '#{entry.name} (#{entry.size} bytes): "
14
13
  puts "'#{zis.gets.chomp}'"
15
14
  entry = zis.get_next_entry
16
15
  print "First line of '#{entry.name} (#{entry.size} bytes): "
17
16
  puts "'#{zis.gets.chomp}'"
18
- }
19
-
17
+ end
20
18
 
21
19
  ####### Using ZipFile to read the directory of a zip file: #######
22
20
 
23
- zf = Zip::ZipFile.new("example.zip")
24
- zf.each_with_index {
25
- |entry, index|
26
-
21
+ zf = Zip::File.new('example.zip')
22
+ zf.each_with_index do |entry, index|
27
23
  puts "entry #{index} is #{entry.name}, size = #{entry.size}, compressed size = #{entry.compressed_size}"
28
24
  # use zf.get_input_stream(entry) to get a ZipInputStream for the entry
29
25
  # entry can be the ZipEntry object or any object which has a to_s method that
30
26
  # returns the name of the entry.
31
- }
32
-
27
+ end
33
28
 
34
29
  ####### Using ZipOutputStream to write a zip file: #######
35
30
 
36
- Zip::ZipOutputStream.open("exampleout.zip") {
37
- |zos|
38
- zos.put_next_entry("the first little entry")
39
- zos.puts "Hello hello hello hello hello hello hello hello hello"
31
+ Zip::OutputStream.open('exampleout.zip') do |zos|
32
+ zos.put_next_entry('the first little entry')
33
+ zos.puts 'Hello hello hello hello hello hello hello hello hello'
40
34
 
41
- zos.put_next_entry("the second little entry")
42
- zos.puts "Hello again"
35
+ zos.put_next_entry('the second little entry')
36
+ zos.puts 'Hello again'
43
37
 
44
38
  # Use rubyzip or your zip client of choice to verify
45
39
  # the contents of exampleout.zip
46
- }
40
+ end
47
41
 
48
42
  ####### Using ZipFile to change a zip file: #######
49
43
 
50
- Zip::ZipFile.open("exampleout.zip") {
51
- |zf|
52
- zf.add("thisFile.rb", "example.rb")
53
- zf.rename("thisFile.rb", "ILikeThisName.rb")
54
- zf.add("Again", "example.rb")
55
- }
44
+ Zip::File.open('exampleout.zip') do |zip_file|
45
+ zip_file.add('thisFile.rb', 'example.rb')
46
+ zip_file.rename('thisFile.rb', 'ILikeThisName.rb')
47
+ zip_file.add('Again', 'example.rb')
48
+ end
56
49
 
57
50
  # Lets check
58
- Zip::ZipFile.open("exampleout.zip") {
59
- |zf|
60
- puts "Changed zip file contains: #{zf.entries.join(', ')}"
61
- zf.remove("Again")
62
- puts "Without 'Again': #{zf.entries.join(', ')}"
63
- }
51
+ Zip::File.open('exampleout.zip') do |zip_file|
52
+ puts "Changed zip file contains: #{zip_file.entries.join(', ')}"
53
+ zip_file.remove('Again')
54
+ puts "Without 'Again': #{zip_file.entries.join(', ')}"
55
+ end
56
+
57
+ ####### Using ZipFile to split a zip file: #######
58
+
59
+ # Creating large zip file for splitting
60
+ Zip::OutputStream.open('large_zip_file.zip') do |zos|
61
+ puts 'Creating zip file...'
62
+ 10.times do |i|
63
+ zos.put_next_entry("large_entry_#{i}.txt")
64
+ zos.puts 'Hello' * 104_857_600
65
+ end
66
+ end
67
+
68
+ # Splitting created large zip file
69
+ part_zips_count = Zip::File.split('large_zip_file.zip', 2_097_152, false)
70
+ puts "Zip file splitted in #{part_zips_count} parts"
71
+
72
+ # Track splitting an archive
73
+ Zip::File.split('large_zip_file.zip', 1_048_576, true, 'part_zip_file') do |part_count, part_index, chunk_bytes, segment_bytes|
74
+ puts "#{part_index} of #{part_count} part splitting: #{(chunk_bytes.to_f / segment_bytes * 100).to_i}%"
75
+ end
64
76
 
65
77
  # For other examples, look at zip.rb and ziptest.rb
66
78
 
@@ -1,31 +1,28 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << "../lib"
3
+ $LOAD_PATH << '../lib'
4
4
 
5
- require 'zip/zipfilesystem'
6
- require 'ftools'
5
+ require 'zip/filesystem'
7
6
 
8
- EXAMPLE_ZIP = "filesystem.zip"
7
+ EXAMPLE_ZIP = 'filesystem.zip'
9
8
 
10
- File.delete(EXAMPLE_ZIP) if File.exists?(EXAMPLE_ZIP)
9
+ File.delete(EXAMPLE_ZIP) if File.exist?(EXAMPLE_ZIP)
11
10
 
12
- Zip::ZipFile.open(EXAMPLE_ZIP, Zip::ZipFile::CREATE) {
13
- |zf|
14
- zf.file.open("file1.txt", "w") { |os| os.write "first file1.txt" }
15
- zf.dir.mkdir("dir1")
16
- zf.dir.chdir("dir1")
17
- zf.file.open("file1.txt", "w") { |os| os.write "second file1.txt" }
18
- puts zf.file.read("file1.txt")
19
- puts zf.file.read("../file1.txt")
20
- zf.dir.chdir("..")
21
- zf.file.open("file2.txt", "w") { |os| os.write "first file2.txt" }
11
+ Zip::File.open(EXAMPLE_ZIP, Zip::File::CREATE) do |zf|
12
+ zf.file.open('file1.txt', 'w') { |os| os.write 'first file1.txt' }
13
+ zf.dir.mkdir('dir1')
14
+ zf.dir.chdir('dir1')
15
+ zf.file.open('file1.txt', 'w') { |os| os.write 'second file1.txt' }
16
+ puts zf.file.read('file1.txt')
17
+ puts zf.file.read('../file1.txt')
18
+ zf.dir.chdir('..')
19
+ zf.file.open('file2.txt', 'w') { |os| os.write 'first file2.txt' }
22
20
  puts "Entries: #{zf.entries.join(', ')}"
23
- }
21
+ end
24
22
 
25
- Zip::ZipFile.open(EXAMPLE_ZIP) {
26
- |zf|
23
+ Zip::File.open(EXAMPLE_ZIP) do |zf|
27
24
  puts "Entries from reloaded zip: #{zf.entries.join(', ')}"
28
- }
25
+ end
29
26
 
30
27
  # For other examples, look at zip.rb and ziptest.rb
31
28
 
@@ -0,0 +1,54 @@
1
+ require 'zip'
2
+
3
+ # This is a simple example which uses rubyzip to
4
+ # recursively generate a zip file from the contents of
5
+ # a specified directory. The directory itself is not
6
+ # included in the archive, rather just its contents.
7
+ #
8
+ # Usage:
9
+ # directory_to_zip = "/tmp/input"
10
+ # output_file = "/tmp/out.zip"
11
+ # zf = ZipFileGenerator.new(directory_to_zip, output_file)
12
+ # zf.write()
13
+ class ZipFileGenerator
14
+ # Initialize with the directory to zip and the location of the output archive.
15
+ def initialize(input_dir, output_file)
16
+ @input_dir = input_dir
17
+ @output_file = output_file
18
+ end
19
+
20
+ # Zip the input directory.
21
+ def write
22
+ entries = Dir.entries(@input_dir) - %w[. ..]
23
+
24
+ ::Zip::File.open(@output_file, ::Zip::File::CREATE) do |zipfile|
25
+ write_entries entries, '', zipfile
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ # A helper method to make the recursion work.
32
+ def write_entries(entries, path, zipfile)
33
+ entries.each do |e|
34
+ zipfile_path = path == '' ? e : File.join(path, e)
35
+ disk_file_path = File.join(@input_dir, zipfile_path)
36
+
37
+ if File.directory? disk_file_path
38
+ recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
39
+ else
40
+ put_into_archive(disk_file_path, zipfile, zipfile_path)
41
+ end
42
+ end
43
+ end
44
+
45
+ def recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
46
+ zipfile.mkdir zipfile_path
47
+ subdir = Dir.entries(disk_file_path) - %w[. ..]
48
+ write_entries subdir, zipfile_path, zipfile
49
+ end
50
+
51
+ def put_into_archive(disk_file_path, zipfile, zipfile_path)
52
+ zipfile.add(zipfile_path, disk_file_path)
53
+ end
54
+ end