rubyzip 0.9.1 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.
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