rubyzip 1.0.0 → 2.4.1
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.
- checksums.yaml +6 -14
- data/README.md +231 -46
- data/Rakefile +13 -5
- data/TODO +0 -1
- data/lib/zip/central_directory.rb +64 -29
- data/lib/zip/compressor.rb +1 -2
- data/lib/zip/constants.rb +59 -5
- data/lib/zip/crypto/decrypted_io.rb +40 -0
- data/lib/zip/crypto/encryption.rb +11 -0
- data/lib/zip/crypto/null_encryption.rb +43 -0
- data/lib/zip/crypto/traditional_encryption.rb +99 -0
- data/lib/zip/decompressor.rb +22 -4
- data/lib/zip/deflater.rb +11 -6
- data/lib/zip/dos_time.rb +27 -16
- data/lib/zip/entry.rb +299 -163
- data/lib/zip/entry_set.rb +22 -20
- data/lib/zip/errors.rb +17 -6
- data/lib/zip/extra_field/generic.rb +15 -14
- data/lib/zip/extra_field/ntfs.rb +94 -0
- data/lib/zip/extra_field/old_unix.rb +46 -0
- data/lib/zip/extra_field/universal_time.rb +46 -16
- data/lib/zip/extra_field/unix.rb +10 -9
- data/lib/zip/extra_field/zip64.rb +46 -6
- data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
- data/lib/zip/extra_field.rb +32 -18
- data/lib/zip/file.rb +260 -160
- data/lib/zip/filesystem.rb +297 -276
- data/lib/zip/inflater.rb +23 -34
- data/lib/zip/input_stream.rb +130 -82
- data/lib/zip/ioextras/abstract_input_stream.rb +36 -22
- data/lib/zip/ioextras/abstract_output_stream.rb +4 -6
- data/lib/zip/ioextras.rb +4 -6
- data/lib/zip/null_compressor.rb +2 -2
- data/lib/zip/null_decompressor.rb +4 -12
- data/lib/zip/null_input_stream.rb +2 -1
- data/lib/zip/output_stream.rb +75 -45
- data/lib/zip/pass_thru_compressor.rb +6 -6
- data/lib/zip/pass_thru_decompressor.rb +14 -24
- data/lib/zip/streamable_directory.rb +3 -3
- data/lib/zip/streamable_stream.rb +21 -16
- data/lib/zip/version.rb +1 -1
- data/lib/zip.rb +42 -3
- data/samples/example.rb +30 -40
- data/samples/example_filesystem.rb +16 -18
- data/samples/example_recursive.rb +33 -28
- data/samples/gtk_ruby_zip.rb +84 -0
- data/samples/qtzip.rb +25 -34
- data/samples/write_simple.rb +10 -13
- data/samples/zipfind.rb +38 -45
- metadata +129 -28
- data/NEWS +0 -182
- data/samples/gtkRubyzip.rb +0 -86
data/lib/zip/output_stream.rb
CHANGED
|
@@ -24,18 +24,25 @@ module Zip
|
|
|
24
24
|
|
|
25
25
|
# Opens the indicated zip file. If a file with that name already
|
|
26
26
|
# exists it will be overwritten.
|
|
27
|
-
def initialize(
|
|
27
|
+
def initialize(file_name, dep_stream = false, dep_encrypter = nil, stream: false, encrypter: nil)
|
|
28
28
|
super()
|
|
29
|
-
|
|
30
|
-
if
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
|
|
30
|
+
Zip.warn_about_v3_api('Zip::OutputStream.new') if dep_stream || !dep_encrypter.nil?
|
|
31
|
+
|
|
32
|
+
@file_name = file_name
|
|
33
|
+
@output_stream = if stream || dep_stream
|
|
34
|
+
iostream = @file_name.dup
|
|
35
|
+
iostream.reopen(@file_name)
|
|
36
|
+
iostream.rewind
|
|
37
|
+
iostream
|
|
38
|
+
else
|
|
39
|
+
::File.new(@file_name, 'wb')
|
|
40
|
+
end
|
|
35
41
|
@entry_set = ::Zip::EntrySet.new
|
|
36
42
|
@compressor = ::Zip::NullCompressor.instance
|
|
43
|
+
@encrypter = encrypter || dep_encrypter || ::Zip::NullEncrypter.new
|
|
37
44
|
@closed = false
|
|
38
|
-
@
|
|
45
|
+
@current_entry = nil
|
|
39
46
|
@comment = nil
|
|
40
47
|
end
|
|
41
48
|
|
|
@@ -43,25 +50,32 @@ module Zip
|
|
|
43
50
|
# stream is passed to the block and closed when the block
|
|
44
51
|
# returns.
|
|
45
52
|
class << self
|
|
46
|
-
def open(
|
|
47
|
-
return new(
|
|
48
|
-
|
|
53
|
+
def open(file_name, dep_encrypter = nil, encrypter: nil)
|
|
54
|
+
return new(file_name) unless block_given?
|
|
55
|
+
|
|
56
|
+
Zip.warn_about_v3_api('Zip::OutputStream.open') unless dep_encrypter.nil?
|
|
57
|
+
|
|
58
|
+
zos = new(file_name, stream: false, encrypter: (encrypter || dep_encrypter))
|
|
49
59
|
yield zos
|
|
50
60
|
ensure
|
|
51
61
|
zos.close if zos
|
|
52
62
|
end
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
def write_buffer
|
|
56
|
-
|
|
64
|
+
# Same as #open but writes to a filestream instead
|
|
65
|
+
def write_buffer(io = ::StringIO.new, dep_encrypter = nil, encrypter: nil)
|
|
66
|
+
Zip.warn_about_v3_api('Zip::OutputStream.write_buffer') unless dep_encrypter.nil?
|
|
67
|
+
|
|
68
|
+
io.binmode if io.respond_to?(:binmode)
|
|
69
|
+
zos = new(io, stream: true, encrypter: (encrypter || dep_encrypter))
|
|
57
70
|
yield zos
|
|
58
|
-
|
|
71
|
+
zos.close_buffer
|
|
59
72
|
end
|
|
60
73
|
end
|
|
61
74
|
|
|
62
75
|
# Closes the stream and writes the central directory to the zip file
|
|
63
76
|
def close
|
|
64
77
|
return if @closed
|
|
78
|
+
|
|
65
79
|
finalize_current_entry
|
|
66
80
|
update_local_headers
|
|
67
81
|
write_central_directory
|
|
@@ -72,6 +86,7 @@ module Zip
|
|
|
72
86
|
# Closes the stream and writes the central directory to the zip file
|
|
73
87
|
def close_buffer
|
|
74
88
|
return @output_stream if @closed
|
|
89
|
+
|
|
75
90
|
finalize_current_entry
|
|
76
91
|
update_local_headers
|
|
77
92
|
write_central_directory
|
|
@@ -79,66 +94,79 @@ module Zip
|
|
|
79
94
|
@output_stream
|
|
80
95
|
end
|
|
81
96
|
|
|
82
|
-
|
|
97
|
+
# Closes the current entry and opens a new for writing.
|
|
83
98
|
# +entry+ can be a ZipEntry object or a string.
|
|
84
|
-
def put_next_entry(
|
|
85
|
-
raise
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
99
|
+
def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
|
|
100
|
+
raise Error, 'zip stream is closed' if @closed
|
|
101
|
+
|
|
102
|
+
new_entry = if entry_name.kind_of?(Entry)
|
|
103
|
+
entry_name
|
|
104
|
+
else
|
|
105
|
+
Entry.new(@file_name, entry_name.to_s)
|
|
106
|
+
end
|
|
107
|
+
new_entry.comment = comment unless comment.nil?
|
|
108
|
+
unless extra.nil?
|
|
109
|
+
new_entry.extra = extra.kind_of?(ExtraField) ? extra : ExtraField.new(extra.to_s)
|
|
94
110
|
end
|
|
95
|
-
new_entry.compression_method = compression_method
|
|
111
|
+
new_entry.compression_method = compression_method unless compression_method.nil?
|
|
96
112
|
init_next_entry(new_entry, level)
|
|
97
|
-
@
|
|
113
|
+
@current_entry = new_entry
|
|
98
114
|
end
|
|
99
115
|
|
|
100
116
|
def copy_raw_entry(entry)
|
|
101
117
|
entry = entry.dup
|
|
102
|
-
raise
|
|
103
|
-
raise
|
|
118
|
+
raise Error, 'zip stream is closed' if @closed
|
|
119
|
+
raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
|
|
120
|
+
|
|
104
121
|
finalize_current_entry
|
|
105
122
|
@entry_set << entry
|
|
106
|
-
src_pos = entry.
|
|
123
|
+
src_pos = entry.local_header_offset
|
|
107
124
|
entry.write_local_entry(@output_stream)
|
|
108
125
|
@compressor = NullCompressor.instance
|
|
109
126
|
entry.get_raw_input_stream do |is|
|
|
110
127
|
is.seek(src_pos, IO::SEEK_SET)
|
|
128
|
+
::Zip::Entry.read_local_entry(is)
|
|
111
129
|
IOExtras.copy_stream_n(@output_stream, is, entry.compressed_size)
|
|
112
130
|
end
|
|
113
131
|
@compressor = NullCompressor.instance
|
|
114
|
-
@
|
|
132
|
+
@current_entry = nil
|
|
115
133
|
end
|
|
116
134
|
|
|
117
135
|
private
|
|
118
136
|
|
|
119
137
|
def finalize_current_entry
|
|
120
|
-
return unless @
|
|
138
|
+
return unless @current_entry
|
|
139
|
+
|
|
121
140
|
finish
|
|
122
|
-
@
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
@
|
|
126
|
-
@
|
|
141
|
+
@current_entry.compressed_size = @output_stream.tell - \
|
|
142
|
+
@current_entry.local_header_offset - \
|
|
143
|
+
@current_entry.calculate_local_header_size
|
|
144
|
+
@current_entry.size = @compressor.size
|
|
145
|
+
@current_entry.crc = @compressor.crc
|
|
146
|
+
@output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size)
|
|
147
|
+
@current_entry.gp_flags |= @encrypter.gp_flags
|
|
148
|
+
@current_entry = nil
|
|
149
|
+
@compressor = ::Zip::NullCompressor.instance
|
|
127
150
|
end
|
|
128
151
|
|
|
129
|
-
def init_next_entry(entry, level =
|
|
152
|
+
def init_next_entry(entry, level = Zip.default_compression)
|
|
130
153
|
finalize_current_entry
|
|
131
154
|
@entry_set << entry
|
|
132
155
|
entry.write_local_entry(@output_stream)
|
|
156
|
+
@encrypter.reset!
|
|
157
|
+
@output_stream << @encrypter.header(entry.mtime)
|
|
133
158
|
@compressor = get_compressor(entry, level)
|
|
134
159
|
end
|
|
135
160
|
|
|
136
161
|
def get_compressor(entry, level)
|
|
137
162
|
case entry.compression_method
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
163
|
+
when Entry::DEFLATED
|
|
164
|
+
::Zip::Deflater.new(@output_stream, level, @encrypter)
|
|
165
|
+
when Entry::STORED
|
|
166
|
+
::Zip::PassThruCompressor.new(@output_stream)
|
|
167
|
+
else
|
|
168
|
+
raise ::Zip::CompressionMethodError,
|
|
169
|
+
"Invalid compression method: '#{entry.compression_method}'"
|
|
142
170
|
end
|
|
143
171
|
end
|
|
144
172
|
|
|
@@ -146,7 +174,7 @@ module Zip
|
|
|
146
174
|
pos = @output_stream.pos
|
|
147
175
|
@entry_set.each do |entry|
|
|
148
176
|
@output_stream.pos = entry.local_header_offset
|
|
149
|
-
entry.write_local_entry(@output_stream)
|
|
177
|
+
entry.write_local_entry(@output_stream, true)
|
|
150
178
|
end
|
|
151
179
|
@output_stream.pos = pos
|
|
152
180
|
end
|
|
@@ -163,9 +191,11 @@ module Zip
|
|
|
163
191
|
end
|
|
164
192
|
|
|
165
193
|
public
|
|
194
|
+
|
|
166
195
|
# Modeled after IO.<<
|
|
167
|
-
def <<
|
|
196
|
+
def <<(data)
|
|
168
197
|
@compressor << data
|
|
198
|
+
self
|
|
169
199
|
end
|
|
170
200
|
end
|
|
171
201
|
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
module Zip
|
|
2
2
|
class PassThruCompressor < Compressor #:nodoc:all
|
|
3
|
-
def initialize(
|
|
3
|
+
def initialize(output_stream)
|
|
4
4
|
super()
|
|
5
|
-
@output_stream =
|
|
6
|
-
@crc = Zlib
|
|
5
|
+
@output_stream = output_stream
|
|
6
|
+
@crc = Zlib.crc32
|
|
7
7
|
@size = 0
|
|
8
8
|
end
|
|
9
|
-
|
|
10
|
-
def <<
|
|
9
|
+
|
|
10
|
+
def <<(data)
|
|
11
11
|
val = data.to_s
|
|
12
|
-
@crc = Zlib
|
|
12
|
+
@crc = Zlib.crc32(val, @crc)
|
|
13
13
|
@size += val.bytesize
|
|
14
14
|
@output_stream << val
|
|
15
15
|
end
|
|
@@ -1,39 +1,29 @@
|
|
|
1
1
|
module Zip
|
|
2
|
-
class PassThruDecompressor < Decompressor
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
super(input_stream)
|
|
6
|
-
@chars_to_read = chars_to_read
|
|
2
|
+
class PassThruDecompressor < Decompressor #:nodoc:all
|
|
3
|
+
def initialize(*args)
|
|
4
|
+
super
|
|
7
5
|
@read_so_far = 0
|
|
8
|
-
@has_returned_empty_string = false
|
|
9
6
|
end
|
|
10
7
|
|
|
11
|
-
def
|
|
12
|
-
if
|
|
13
|
-
has_returned_empty_string_val = @has_returned_empty_string
|
|
14
|
-
@has_returned_empty_string = true
|
|
15
|
-
return '' unless has_returned_empty_string_val
|
|
16
|
-
return
|
|
17
|
-
end
|
|
8
|
+
def read(length = nil, outbuf = ''.b)
|
|
9
|
+
return (length.nil? || length.zero? ? '' : nil) if eof
|
|
18
10
|
|
|
19
|
-
if
|
|
20
|
-
|
|
11
|
+
if length.nil? || (@read_so_far + length) > decompressed_size
|
|
12
|
+
length = decompressed_size - @read_so_far
|
|
21
13
|
end
|
|
22
|
-
@read_so_far += number_of_bytes
|
|
23
|
-
@input_stream.read(number_of_bytes, buf)
|
|
24
|
-
end
|
|
25
14
|
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
@read_so_far += length
|
|
16
|
+
input_stream.read(length, outbuf)
|
|
28
17
|
end
|
|
29
18
|
|
|
30
|
-
def
|
|
31
|
-
@read_so_far >=
|
|
19
|
+
def eof
|
|
20
|
+
@read_so_far >= decompressed_size
|
|
32
21
|
end
|
|
33
22
|
|
|
34
|
-
alias
|
|
35
|
-
alias :eof? :input_finished?
|
|
23
|
+
alias eof? eof
|
|
36
24
|
end
|
|
25
|
+
|
|
26
|
+
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
|
|
37
27
|
end
|
|
38
28
|
|
|
39
29
|
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module Zip
|
|
2
2
|
class StreamableDirectory < Entry
|
|
3
|
-
def initialize(zipfile, entry,
|
|
3
|
+
def initialize(zipfile, entry, src_path = nil, permission = nil)
|
|
4
4
|
super(zipfile, entry)
|
|
5
5
|
|
|
6
6
|
@ftype = :directory
|
|
7
|
-
entry.get_extra_attributes_from_path(
|
|
8
|
-
@unix_perms =
|
|
7
|
+
entry.get_extra_attributes_from_path(src_path) if src_path
|
|
8
|
+
@unix_perms = permission if permission
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -1,43 +1,48 @@
|
|
|
1
1
|
module Zip
|
|
2
|
-
class StreamableStream < DelegateClass(Entry) #nodoc:all
|
|
2
|
+
class StreamableStream < DelegateClass(Entry) # :nodoc:all
|
|
3
3
|
def initialize(entry)
|
|
4
4
|
super(entry)
|
|
5
|
-
@
|
|
6
|
-
@
|
|
5
|
+
@temp_file = Tempfile.new(::File.basename(name))
|
|
6
|
+
@temp_file.binmode
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
def get_output_stream
|
|
10
10
|
if block_given?
|
|
11
11
|
begin
|
|
12
|
-
yield(@
|
|
12
|
+
yield(@temp_file)
|
|
13
13
|
ensure
|
|
14
|
-
@
|
|
14
|
+
@temp_file.close
|
|
15
15
|
end
|
|
16
16
|
else
|
|
17
|
-
@
|
|
17
|
+
@temp_file
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def get_input_stream
|
|
22
|
-
|
|
22
|
+
unless @temp_file.closed?
|
|
23
23
|
raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
|
|
24
24
|
end
|
|
25
|
-
|
|
26
|
-
@
|
|
25
|
+
|
|
26
|
+
@temp_file.open # reopens tempfile from top
|
|
27
|
+
@temp_file.binmode
|
|
27
28
|
if block_given?
|
|
28
29
|
begin
|
|
29
|
-
yield(@
|
|
30
|
+
yield(@temp_file)
|
|
30
31
|
ensure
|
|
31
|
-
@
|
|
32
|
+
@temp_file.close
|
|
32
33
|
end
|
|
33
34
|
else
|
|
34
|
-
@
|
|
35
|
+
@temp_file
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
|
-
|
|
38
|
-
def write_to_zip_output_stream(
|
|
39
|
-
|
|
40
|
-
get_input_stream { |is| ::Zip::IOExtras.copy_stream(
|
|
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
|
|
41
46
|
end
|
|
42
47
|
end
|
|
43
48
|
end
|
data/lib/zip/version.rb
CHANGED
data/lib/zip.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
require 'English'
|
|
1
2
|
require 'delegate'
|
|
2
3
|
require 'singleton'
|
|
3
4
|
require 'tempfile'
|
|
4
5
|
require 'fileutils'
|
|
5
6
|
require 'stringio'
|
|
6
7
|
require 'zlib'
|
|
8
|
+
require 'zip/constants'
|
|
7
9
|
require 'zip/dos_time'
|
|
8
10
|
require 'zip/ioextras'
|
|
9
11
|
require 'rbconfig'
|
|
@@ -21,22 +23,59 @@ require 'zip/null_compressor'
|
|
|
21
23
|
require 'zip/null_input_stream'
|
|
22
24
|
require 'zip/pass_thru_compressor'
|
|
23
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'
|
|
24
30
|
require 'zip/inflater'
|
|
25
31
|
require 'zip/deflater'
|
|
26
32
|
require 'zip/streamable_stream'
|
|
27
33
|
require 'zip/streamable_directory'
|
|
28
|
-
require 'zip/constants'
|
|
29
34
|
require 'zip/errors'
|
|
30
35
|
|
|
31
36
|
module Zip
|
|
37
|
+
V3_API_WARNING_MSG = <<~END_MSG
|
|
38
|
+
You have called '%s' (from %s).
|
|
39
|
+
This method is changing or deprecated in version 3.0.0. Please see
|
|
40
|
+
https://github.com/rubyzip/rubyzip/wiki/Updating-to-version-3.x
|
|
41
|
+
for more information.
|
|
42
|
+
END_MSG
|
|
43
|
+
|
|
44
|
+
def self.warn_about_v3_api(method)
|
|
45
|
+
return unless ENV['RUBYZIP_V3_API_WARN']
|
|
46
|
+
|
|
47
|
+
loc = caller_locations(2, 1)[0]
|
|
48
|
+
from = "#{loc.path.split('/').last}:#{loc.lineno}"
|
|
49
|
+
warn format(V3_API_WARNING_MSG, method, from)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
if ENV['RUBYZIP_V3_API_WARN'] && RUBY_VERSION < '3.0'
|
|
53
|
+
warn 'RubyZip 3.0 will require Ruby 3.0 or later.'
|
|
54
|
+
end
|
|
55
|
+
|
|
32
56
|
extend self
|
|
33
|
-
attr_accessor :unicode_names,
|
|
57
|
+
attr_accessor :unicode_names,
|
|
58
|
+
:on_exists_proc,
|
|
59
|
+
:continue_on_exists_proc,
|
|
60
|
+
:sort_entries,
|
|
61
|
+
:default_compression,
|
|
62
|
+
:write_zip64_support,
|
|
63
|
+
:warn_invalid_date,
|
|
64
|
+
:case_insensitive_match,
|
|
65
|
+
:force_entry_names_encoding,
|
|
66
|
+
:validate_entry_sizes
|
|
34
67
|
|
|
35
68
|
def reset!
|
|
36
69
|
@_ran_once = false
|
|
37
70
|
@unicode_names = false
|
|
38
71
|
@on_exists_proc = false
|
|
39
72
|
@continue_on_exists_proc = false
|
|
73
|
+
@sort_entries = false
|
|
74
|
+
@default_compression = ::Zlib::DEFAULT_COMPRESSION
|
|
75
|
+
@write_zip64_support = false
|
|
76
|
+
@warn_invalid_date = true
|
|
77
|
+
@case_insensitive_match = false
|
|
78
|
+
@validate_entry_sizes = true
|
|
40
79
|
end
|
|
41
80
|
|
|
42
81
|
def setup
|
|
@@ -49,4 +88,4 @@ end
|
|
|
49
88
|
|
|
50
89
|
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
51
90
|
# rubyzip is free software; you can redistribute it and/or
|
|
52
|
-
# modify it under the terms of the ruby license.
|
|
91
|
+
# modify it under the terms of the ruby license.
|
data/samples/example.rb
CHANGED
|
@@ -1,89 +1,79 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
system(
|
|
3
|
+
$LOAD_PATH << '../lib'
|
|
4
|
+
system('zip example.zip example.rb gtk_ruby_zip.rb')
|
|
5
5
|
|
|
6
|
-
require 'zip
|
|
6
|
+
require 'zip'
|
|
7
7
|
|
|
8
8
|
####### Using ZipInputStream alone: #######
|
|
9
9
|
|
|
10
|
-
Zip::InputStream.open(
|
|
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::File.new(
|
|
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::OutputStream.open(
|
|
37
|
-
|
|
38
|
-
zos.
|
|
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(
|
|
42
|
-
zos.puts
|
|
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::File.open(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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::File.open(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
64
56
|
|
|
65
57
|
####### Using ZipFile to split a zip file: #######
|
|
66
58
|
|
|
67
59
|
# Creating large zip file for splitting
|
|
68
|
-
Zip::OutputStream.open(
|
|
69
|
-
puts
|
|
60
|
+
Zip::OutputStream.open('large_zip_file.zip') do |zos|
|
|
61
|
+
puts 'Creating zip file...'
|
|
70
62
|
10.times do |i|
|
|
71
63
|
zos.put_next_entry("large_entry_#{i}.txt")
|
|
72
|
-
zos.puts
|
|
64
|
+
zos.puts 'Hello' * 104_857_600
|
|
73
65
|
end
|
|
74
66
|
end
|
|
75
67
|
|
|
76
68
|
# Splitting created large zip file
|
|
77
|
-
part_zips_count = Zip::File.split(
|
|
69
|
+
part_zips_count = Zip::File.split('large_zip_file.zip', 2_097_152, false)
|
|
78
70
|
puts "Zip file splitted in #{part_zips_count} parts"
|
|
79
71
|
|
|
80
72
|
# Track splitting an archive
|
|
81
|
-
Zip::File.split(
|
|
82
|
-
|
|
83
|
-
puts "#{part_index} of #{part_count} part splitting: #{(chunk_bytes.to_f/segment_bytes.to_f * 100).to_i}%"
|
|
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}%"
|
|
84
75
|
end
|
|
85
76
|
|
|
86
|
-
|
|
87
77
|
# For other examples, look at zip.rb and ziptest.rb
|
|
88
78
|
|
|
89
79
|
# Copyright (C) 2002 Thomas Sondergaard
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
$LOAD_PATH << '../lib'
|
|
4
4
|
|
|
5
|
-
require 'zip/
|
|
5
|
+
require 'zip/filesystem'
|
|
6
6
|
|
|
7
|
-
EXAMPLE_ZIP =
|
|
7
|
+
EXAMPLE_ZIP = 'filesystem.zip'
|
|
8
8
|
|
|
9
|
-
File.delete(EXAMPLE_ZIP) if File.
|
|
9
|
+
File.delete(EXAMPLE_ZIP) if File.exist?(EXAMPLE_ZIP)
|
|
10
10
|
|
|
11
|
-
Zip::File.open(EXAMPLE_ZIP, Zip::File::CREATE)
|
|
12
|
-
|
|
13
|
-
zf.
|
|
14
|
-
zf.dir.
|
|
15
|
-
zf.
|
|
16
|
-
zf.file.
|
|
17
|
-
puts zf.file.read(
|
|
18
|
-
|
|
19
|
-
zf.
|
|
20
|
-
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' }
|
|
21
20
|
puts "Entries: #{zf.entries.join(', ')}"
|
|
22
|
-
|
|
21
|
+
end
|
|
23
22
|
|
|
24
|
-
Zip::File.open(EXAMPLE_ZIP)
|
|
25
|
-
|zf|
|
|
23
|
+
Zip::File.open(EXAMPLE_ZIP) do |zf|
|
|
26
24
|
puts "Entries from reloaded zip: #{zf.entries.join(', ')}"
|
|
27
|
-
|
|
25
|
+
end
|
|
28
26
|
|
|
29
27
|
# For other examples, look at zip.rb and ziptest.rb
|
|
30
28
|
|