rubyzip 2.3.2 → 3.3.0
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 +4 -4
- data/Changelog.md +495 -0
- data/LICENSE.md +24 -0
- data/README.md +192 -44
- data/Rakefile +15 -13
- data/lib/zip/central_directory.rb +179 -125
- data/lib/zip/compressor.rb +3 -1
- data/lib/zip/constants.rb +29 -21
- data/lib/zip/crypto/aes_encryption.rb +120 -0
- data/lib/zip/crypto/decrypted_io.rb +21 -15
- data/lib/zip/crypto/encryption.rb +4 -2
- data/lib/zip/crypto/null_encryption.rb +5 -13
- data/lib/zip/crypto/traditional_encryption.rb +10 -6
- data/lib/zip/decompressor.rb +4 -3
- data/lib/zip/deflater.rb +12 -8
- data/lib/zip/dirtyable.rb +32 -0
- data/lib/zip/dos_time.rb +53 -6
- data/lib/zip/entry.rb +405 -240
- data/lib/zip/entry_set.rb +11 -9
- data/lib/zip/errors.rb +136 -16
- data/lib/zip/extra_field/aes.rb +50 -0
- data/lib/zip/extra_field/generic.rb +10 -11
- data/lib/zip/extra_field/ntfs.rb +6 -4
- data/lib/zip/extra_field/old_unix.rb +3 -1
- data/lib/zip/extra_field/universal_time.rb +3 -1
- data/lib/zip/extra_field/unix.rb +5 -3
- data/lib/zip/extra_field/unknown.rb +35 -0
- data/lib/zip/extra_field/zip64.rb +19 -5
- data/lib/zip/extra_field.rb +25 -23
- data/lib/zip/file.rb +185 -226
- data/lib/zip/file_split.rb +91 -0
- data/lib/zip/filesystem/dir.rb +86 -0
- data/lib/zip/filesystem/directory_iterator.rb +48 -0
- data/lib/zip/filesystem/file.rb +263 -0
- data/lib/zip/filesystem/file_stat.rb +110 -0
- data/lib/zip/filesystem/zip_file_name_mapper.rb +81 -0
- data/lib/zip/filesystem.rb +27 -596
- data/lib/zip/inflater.rb +13 -10
- data/lib/zip/input_stream.rb +98 -47
- data/lib/zip/ioextras/abstract_input_stream.rb +146 -58
- data/lib/zip/ioextras/abstract_output_stream.rb +13 -3
- data/lib/zip/ioextras.rb +7 -7
- data/lib/zip/null_compressor.rb +3 -1
- data/lib/zip/null_decompressor.rb +6 -3
- data/lib/zip/null_input_stream.rb +3 -1
- data/lib/zip/output_stream.rb +58 -48
- data/lib/zip/pass_thru_compressor.rb +3 -1
- data/lib/zip/pass_thru_decompressor.rb +12 -9
- data/lib/zip/streamable_directory.rb +3 -1
- data/lib/zip/streamable_stream.rb +4 -1
- data/lib/zip/version.rb +4 -1
- data/lib/zip.rb +25 -3
- data/rubyzip.gemspec +39 -0
- data/samples/example.rb +8 -3
- data/samples/example_filesystem.rb +3 -2
- data/samples/example_recursive.rb +3 -1
- data/samples/gtk_ruby_zip.rb +5 -3
- data/samples/qtzip.rb +7 -6
- data/samples/write_simple.rb +2 -1
- data/samples/zipfind.rb +1 -0
- metadata +81 -49
- data/TODO +0 -15
- data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
data/lib/zip/output_stream.rb
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
##
|
|
1
6
|
module Zip
|
|
2
7
|
# ZipOutputStream is the basic class for writing zip files. It is
|
|
3
8
|
# possible to create a ZipOutputStream object directly, passing
|
|
@@ -16,50 +21,52 @@ module Zip
|
|
|
16
21
|
#
|
|
17
22
|
# java.util.zip.ZipOutputStream is the original inspiration for this
|
|
18
23
|
# class.
|
|
19
|
-
|
|
20
24
|
class OutputStream
|
|
25
|
+
extend Forwardable
|
|
21
26
|
include ::Zip::IOExtras::AbstractOutputStream
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
def_delegators :@cdir, :comment, :comment=
|
|
24
29
|
|
|
25
30
|
# Opens the indicated zip file. If a file with that name already
|
|
26
31
|
# exists it will be overwritten.
|
|
27
|
-
def initialize(file_name, stream
|
|
32
|
+
def initialize(file_name, stream: false, encrypter: nil, suppress_extra_fields: false)
|
|
28
33
|
super()
|
|
29
34
|
@file_name = file_name
|
|
30
35
|
@output_stream = if stream
|
|
31
|
-
iostream = @file_name.dup
|
|
36
|
+
iostream = Zip::RUNNING_ON_WINDOWS ? @file_name : @file_name.dup
|
|
32
37
|
iostream.reopen(@file_name)
|
|
33
38
|
iostream.rewind
|
|
34
39
|
iostream
|
|
35
40
|
else
|
|
36
41
|
::File.new(@file_name, 'wb')
|
|
37
42
|
end
|
|
38
|
-
@
|
|
43
|
+
@cdir = ::Zip::CentralDirectory.new
|
|
39
44
|
@compressor = ::Zip::NullCompressor.instance
|
|
40
45
|
@encrypter = encrypter || ::Zip::NullEncrypter.new
|
|
46
|
+
@suppress_extra_fields = suppress_extra_fields
|
|
41
47
|
@closed = false
|
|
42
48
|
@current_entry = nil
|
|
43
|
-
@comment = nil
|
|
44
49
|
end
|
|
45
50
|
|
|
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
51
|
class << self
|
|
50
|
-
|
|
52
|
+
# Same as #initialize but if a block is passed the opened
|
|
53
|
+
# stream is passed to the block and closed when the block
|
|
54
|
+
# returns.
|
|
55
|
+
def open(file_name, encrypter: nil, suppress_extra_fields: false)
|
|
51
56
|
return new(file_name) unless block_given?
|
|
52
57
|
|
|
53
|
-
zos = new(file_name, false, encrypter
|
|
58
|
+
zos = new(file_name, stream: false, encrypter: encrypter,
|
|
59
|
+
suppress_extra_fields: suppress_extra_fields)
|
|
54
60
|
yield zos
|
|
55
61
|
ensure
|
|
56
62
|
zos.close if zos
|
|
57
63
|
end
|
|
58
64
|
|
|
59
65
|
# Same as #open but writes to a filestream instead
|
|
60
|
-
def write_buffer(io = ::StringIO.new
|
|
66
|
+
def write_buffer(io = ::StringIO.new, encrypter: nil, suppress_extra_fields: false)
|
|
61
67
|
io.binmode if io.respond_to?(:binmode)
|
|
62
|
-
zos = new(io, true, encrypter
|
|
68
|
+
zos = new(io, stream: true, encrypter: encrypter,
|
|
69
|
+
suppress_extra_fields: suppress_extra_fields)
|
|
63
70
|
yield zos
|
|
64
71
|
zos.close_buffer
|
|
65
72
|
end
|
|
@@ -71,7 +78,7 @@ module Zip
|
|
|
71
78
|
|
|
72
79
|
finalize_current_entry
|
|
73
80
|
update_local_headers
|
|
74
|
-
|
|
81
|
+
@cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
75
82
|
@output_stream.close
|
|
76
83
|
@closed = true
|
|
77
84
|
end
|
|
@@ -82,37 +89,41 @@ module Zip
|
|
|
82
89
|
|
|
83
90
|
finalize_current_entry
|
|
84
91
|
update_local_headers
|
|
85
|
-
|
|
92
|
+
@cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
86
93
|
@closed = true
|
|
94
|
+
@output_stream.flush
|
|
87
95
|
@output_stream
|
|
88
96
|
end
|
|
89
97
|
|
|
90
98
|
# Closes the current entry and opens a new for writing.
|
|
91
99
|
# +entry+ can be a ZipEntry object or a string.
|
|
92
|
-
def put_next_entry(
|
|
100
|
+
def put_next_entry(
|
|
101
|
+
entry_name, comment = '', extra = ExtraField.new,
|
|
102
|
+
compression_method = Entry::DEFLATED, level = Zip.default_compression
|
|
103
|
+
)
|
|
93
104
|
raise Error, 'zip stream is closed' if @closed
|
|
94
105
|
|
|
95
|
-
new_entry =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
init_next_entry(new_entry
|
|
106
|
+
new_entry =
|
|
107
|
+
if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream)
|
|
108
|
+
entry_name
|
|
109
|
+
else
|
|
110
|
+
Entry.new(
|
|
111
|
+
@file_name, entry_name.to_s, comment: comment, extra: extra,
|
|
112
|
+
compression_method: compression_method, compression_level: level
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
init_next_entry(new_entry)
|
|
106
117
|
@current_entry = new_entry
|
|
107
118
|
end
|
|
108
119
|
|
|
109
|
-
def copy_raw_entry(entry)
|
|
120
|
+
def copy_raw_entry(entry) # :nodoc:
|
|
110
121
|
entry = entry.dup
|
|
111
122
|
raise Error, 'zip stream is closed' if @closed
|
|
112
123
|
raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
|
|
113
124
|
|
|
114
125
|
finalize_current_entry
|
|
115
|
-
@
|
|
126
|
+
@cdir << entry
|
|
116
127
|
src_pos = entry.local_header_offset
|
|
117
128
|
entry.write_local_entry(@output_stream)
|
|
118
129
|
@compressor = NullCompressor.instance
|
|
@@ -131,55 +142,54 @@ module Zip
|
|
|
131
142
|
return unless @current_entry
|
|
132
143
|
|
|
133
144
|
finish
|
|
134
|
-
@current_entry.compressed_size = @output_stream.tell -
|
|
135
|
-
@current_entry.local_header_offset -
|
|
145
|
+
@current_entry.compressed_size = @output_stream.tell -
|
|
146
|
+
@current_entry.local_header_offset -
|
|
136
147
|
@current_entry.calculate_local_header_size
|
|
137
148
|
@current_entry.size = @compressor.size
|
|
138
149
|
@current_entry.crc = @compressor.crc
|
|
139
|
-
@output_stream << @encrypter.data_descriptor(
|
|
150
|
+
@output_stream << @encrypter.data_descriptor(
|
|
151
|
+
@current_entry.crc,
|
|
152
|
+
@current_entry.compressed_size,
|
|
153
|
+
@current_entry.size
|
|
154
|
+
)
|
|
140
155
|
@current_entry.gp_flags |= @encrypter.gp_flags
|
|
141
156
|
@current_entry = nil
|
|
142
157
|
@compressor = ::Zip::NullCompressor.instance
|
|
143
158
|
end
|
|
144
159
|
|
|
145
|
-
def init_next_entry(entry
|
|
160
|
+
def init_next_entry(entry)
|
|
146
161
|
finalize_current_entry
|
|
147
|
-
@
|
|
148
|
-
entry.write_local_entry(@output_stream)
|
|
162
|
+
@cdir << entry
|
|
163
|
+
entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
149
164
|
@encrypter.reset!
|
|
150
165
|
@output_stream << @encrypter.header(entry.mtime)
|
|
151
|
-
@compressor = get_compressor(entry
|
|
166
|
+
@compressor = get_compressor(entry)
|
|
152
167
|
end
|
|
153
168
|
|
|
154
|
-
def get_compressor(entry
|
|
169
|
+
def get_compressor(entry)
|
|
155
170
|
case entry.compression_method
|
|
156
171
|
when Entry::DEFLATED
|
|
157
|
-
::Zip::Deflater.new(@output_stream,
|
|
172
|
+
::Zip::Deflater.new(@output_stream, entry.compression_level, @encrypter)
|
|
158
173
|
when Entry::STORED
|
|
159
174
|
::Zip::PassThruCompressor.new(@output_stream)
|
|
160
175
|
else
|
|
161
|
-
raise ::Zip::CompressionMethodError,
|
|
162
|
-
"Invalid compression method: '#{entry.compression_method}'"
|
|
176
|
+
raise ::Zip::CompressionMethodError, entry.compression_method
|
|
163
177
|
end
|
|
164
178
|
end
|
|
165
179
|
|
|
166
180
|
def update_local_headers
|
|
167
181
|
pos = @output_stream.pos
|
|
168
|
-
@
|
|
182
|
+
@cdir.each do |entry|
|
|
169
183
|
@output_stream.pos = entry.local_header_offset
|
|
170
|
-
entry.write_local_entry(@output_stream,
|
|
184
|
+
entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields,
|
|
185
|
+
rewrite: true)
|
|
171
186
|
end
|
|
172
187
|
@output_stream.pos = pos
|
|
173
188
|
end
|
|
174
189
|
|
|
175
|
-
def write_central_directory
|
|
176
|
-
cdir = CentralDirectory.new(@entry_set, @comment)
|
|
177
|
-
cdir.write_to_stream(@output_stream)
|
|
178
|
-
end
|
|
179
|
-
|
|
180
190
|
protected
|
|
181
191
|
|
|
182
|
-
def finish
|
|
192
|
+
def finish # :nodoc:
|
|
183
193
|
@compressor.finish
|
|
184
194
|
end
|
|
185
195
|
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Zip
|
|
2
|
-
class PassThruDecompressor < Decompressor
|
|
4
|
+
class PassThruDecompressor < Decompressor # :nodoc:all
|
|
3
5
|
def initialize(*args)
|
|
4
6
|
super
|
|
5
7
|
@read_so_far = 0
|
|
6
8
|
end
|
|
7
9
|
|
|
8
|
-
def read(
|
|
9
|
-
return (
|
|
10
|
+
def read(maxlen = nil)
|
|
11
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
10
12
|
|
|
11
|
-
if
|
|
12
|
-
|
|
13
|
+
if maxlen.nil? || (@read_so_far + maxlen) > decompressed_size
|
|
14
|
+
maxlen = decompressed_size - @read_so_far
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
@read_so_far +=
|
|
16
|
-
input_stream.read(
|
|
17
|
+
@read_so_far += maxlen
|
|
18
|
+
input_stream.read(maxlen)
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def eof
|
|
21
|
+
def eof?
|
|
20
22
|
@read_so_far >= decompressed_size
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
# Alias for compatibility. Remove for version 4.
|
|
26
|
+
alias eof eof?
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Zip
|
|
2
4
|
class StreamableStream < DelegateClass(Entry) # :nodoc:all
|
|
3
5
|
def initialize(entry)
|
|
4
|
-
super
|
|
6
|
+
super
|
|
5
7
|
@temp_file = Tempfile.new(::File.basename(name))
|
|
6
8
|
@temp_file.binmode
|
|
7
9
|
end
|
|
@@ -42,6 +44,7 @@ module Zip
|
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
def clean_up
|
|
47
|
+
super
|
|
45
48
|
@temp_file.unlink
|
|
46
49
|
end
|
|
47
50
|
end
|
data/lib/zip/version.rb
CHANGED
data/lib/zip.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'English'
|
|
2
4
|
require 'delegate'
|
|
3
5
|
require 'singleton'
|
|
@@ -5,6 +7,7 @@ require 'tempfile'
|
|
|
5
7
|
require 'fileutils'
|
|
6
8
|
require 'stringio'
|
|
7
9
|
require 'zlib'
|
|
10
|
+
require 'zip/version'
|
|
8
11
|
require 'zip/constants'
|
|
9
12
|
require 'zip/dos_time'
|
|
10
13
|
require 'zip/ioextras'
|
|
@@ -27,14 +30,21 @@ require 'zip/crypto/decrypted_io'
|
|
|
27
30
|
require 'zip/crypto/encryption'
|
|
28
31
|
require 'zip/crypto/null_encryption'
|
|
29
32
|
require 'zip/crypto/traditional_encryption'
|
|
33
|
+
require 'zip/crypto/aes_encryption'
|
|
30
34
|
require 'zip/inflater'
|
|
31
35
|
require 'zip/deflater'
|
|
32
36
|
require 'zip/streamable_stream'
|
|
33
37
|
require 'zip/streamable_directory'
|
|
34
38
|
require 'zip/errors'
|
|
35
39
|
|
|
40
|
+
# Rubyzip is a ruby module for reading and writing zip files.
|
|
41
|
+
#
|
|
42
|
+
# The main entry points are File, InputStream and OutputStream. For a
|
|
43
|
+
# file/directory interface in the style of the standard ruby ::File and
|
|
44
|
+
# ::Dir APIs then `require 'zip/filesystem'` and see FileSystem.
|
|
36
45
|
module Zip
|
|
37
46
|
extend self
|
|
47
|
+
|
|
38
48
|
attr_accessor :unicode_names,
|
|
39
49
|
:on_exists_proc,
|
|
40
50
|
:continue_on_exists_proc,
|
|
@@ -46,19 +56,31 @@ module Zip
|
|
|
46
56
|
:force_entry_names_encoding,
|
|
47
57
|
:validate_entry_sizes
|
|
48
58
|
|
|
49
|
-
|
|
59
|
+
DEFAULT_RESTORE_OPTIONS = {
|
|
60
|
+
restore_ownership: false,
|
|
61
|
+
restore_permissions: true,
|
|
62
|
+
restore_times: true
|
|
63
|
+
}.freeze # :nodoc:
|
|
64
|
+
|
|
65
|
+
# :nodoc:
|
|
66
|
+
# Remove this when JRuby#3962 is fixed.
|
|
67
|
+
ZLIB_FLUSHING_STRATEGY = defined?(JRUBY_VERSION) ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
|
|
68
|
+
|
|
69
|
+
def reset! # :nodoc:
|
|
50
70
|
@_ran_once = false
|
|
51
71
|
@unicode_names = false
|
|
52
72
|
@on_exists_proc = false
|
|
53
73
|
@continue_on_exists_proc = false
|
|
54
74
|
@sort_entries = false
|
|
55
|
-
@default_compression =
|
|
56
|
-
@write_zip64_support =
|
|
75
|
+
@default_compression = Zlib::DEFAULT_COMPRESSION
|
|
76
|
+
@write_zip64_support = true
|
|
57
77
|
@warn_invalid_date = true
|
|
58
78
|
@case_insensitive_match = false
|
|
79
|
+
@force_entry_names_encoding = nil
|
|
59
80
|
@validate_entry_sizes = true
|
|
60
81
|
end
|
|
61
82
|
|
|
83
|
+
# Set options for RubyZip in one block.
|
|
62
84
|
def setup
|
|
63
85
|
yield self unless @_ran_once
|
|
64
86
|
@_ran_once = true
|
data/rubyzip.gemspec
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/zip/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'rubyzip'
|
|
7
|
+
s.version = Zip::VERSION
|
|
8
|
+
s.authors = ['Robert Haines', 'John Lees-Miller', 'Alexander Simonov']
|
|
9
|
+
s.email = [
|
|
10
|
+
'hainesr@gmail.com', 'jdleesmiller@gmail.com', 'alex@simonov.me'
|
|
11
|
+
]
|
|
12
|
+
s.homepage = 'http://github.com/rubyzip/rubyzip'
|
|
13
|
+
s.platform = Gem::Platform::RUBY
|
|
14
|
+
s.summary = 'rubyzip is a ruby module for reading and writing zip files'
|
|
15
|
+
s.files = Dir.glob('{samples,lib}/**/*.rb') +
|
|
16
|
+
%w[LICENSE.md README.md Changelog.md Rakefile rubyzip.gemspec]
|
|
17
|
+
s.require_paths = ['lib']
|
|
18
|
+
s.license = 'BSD-2-Clause'
|
|
19
|
+
|
|
20
|
+
s.metadata = {
|
|
21
|
+
'bug_tracker_uri' => 'https://github.com/rubyzip/rubyzip/issues',
|
|
22
|
+
'changelog_uri' => "https://github.com/rubyzip/rubyzip/blob/v#{s.version}/Changelog.md",
|
|
23
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/rubyzip/#{s.version}",
|
|
24
|
+
'source_code_uri' => "https://github.com/rubyzip/rubyzip/tree/v#{s.version}",
|
|
25
|
+
'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki',
|
|
26
|
+
'rubygems_mfa_required' => 'true'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
s.required_ruby_version = '>= 3.0'
|
|
30
|
+
|
|
31
|
+
s.add_development_dependency 'minitest', '~> 5.25'
|
|
32
|
+
s.add_development_dependency 'rake', '~> 13.2'
|
|
33
|
+
s.add_development_dependency 'rdoc', '~> 6.11'
|
|
34
|
+
s.add_development_dependency 'rubocop', '~> 1.80.2'
|
|
35
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.26.0'
|
|
36
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.7.1'
|
|
37
|
+
s.add_development_dependency 'simplecov', '~> 0.22.0'
|
|
38
|
+
s.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
|
39
|
+
end
|
data/samples/example.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
system('zip example.zip example.rb gtk_ruby_zip.rb')
|
|
@@ -20,7 +21,8 @@ end
|
|
|
20
21
|
|
|
21
22
|
zf = Zip::File.new('example.zip')
|
|
22
23
|
zf.each_with_index do |entry, index|
|
|
23
|
-
puts "entry #{index} is #{entry.name}, size = #{entry.size},
|
|
24
|
+
puts "entry #{index} is #{entry.name}, size = #{entry.size}, " \
|
|
25
|
+
"compressed size = #{entry.compressed_size}"
|
|
24
26
|
# use zf.get_input_stream(entry) to get a ZipInputStream for the entry
|
|
25
27
|
# entry can be the ZipEntry object or any object which has a to_s method that
|
|
26
28
|
# returns the name of the entry.
|
|
@@ -70,8 +72,11 @@ part_zips_count = Zip::File.split('large_zip_file.zip', 2_097_152, false)
|
|
|
70
72
|
puts "Zip file splitted in #{part_zips_count} parts"
|
|
71
73
|
|
|
72
74
|
# Track splitting an archive
|
|
73
|
-
Zip::File.split(
|
|
74
|
-
|
|
75
|
+
Zip::File.split(
|
|
76
|
+
'large_zip_file.zip', 1_048_576, true, 'part_zip_file'
|
|
77
|
+
) do |part_count, part_index, chunk_bytes, segment_bytes|
|
|
78
|
+
puts "#{part_index} of #{part_count} part splitting: " \
|
|
79
|
+
"#{(chunk_bytes.to_f / segment_bytes * 100).to_i}%"
|
|
75
80
|
end
|
|
76
81
|
|
|
77
82
|
# For other examples, look at zip.rb and ziptest.rb
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
@@ -6,9 +7,9 @@ require 'zip/filesystem'
|
|
|
6
7
|
|
|
7
8
|
EXAMPLE_ZIP = 'filesystem.zip'
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
FileUtils.rm_f(EXAMPLE_ZIP)
|
|
10
11
|
|
|
11
|
-
Zip::File.open(EXAMPLE_ZIP,
|
|
12
|
+
Zip::File.open(EXAMPLE_ZIP, create: true) do |zf|
|
|
12
13
|
zf.file.open('file1.txt', 'w') { |os| os.write 'first file1.txt' }
|
|
13
14
|
zf.dir.mkdir('dir1')
|
|
14
15
|
zf.dir.chdir('dir1')
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'zip'
|
|
2
4
|
|
|
3
5
|
# This is a simple example which uses rubyzip to
|
|
@@ -21,7 +23,7 @@ class ZipFileGenerator
|
|
|
21
23
|
def write
|
|
22
24
|
entries = Dir.entries(@input_dir) - %w[. ..]
|
|
23
25
|
|
|
24
|
-
::Zip::File.open(@output_file,
|
|
26
|
+
::Zip::File.open(@output_file, create: true) do |zipfile|
|
|
25
27
|
write_entries entries, '', zipfile
|
|
26
28
|
end
|
|
27
29
|
end
|
data/samples/gtk_ruby_zip.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
@@ -9,7 +10,7 @@ require 'zip'
|
|
|
9
10
|
|
|
10
11
|
class MainApp < Gtk::Window
|
|
11
12
|
def initialize
|
|
12
|
-
super
|
|
13
|
+
super
|
|
13
14
|
set_usize(400, 256)
|
|
14
15
|
set_title('rubyzip')
|
|
15
16
|
signal_connect(Gtk::Window::SIGNAL_DESTROY) { Gtk.main_quit }
|
|
@@ -42,7 +43,8 @@ class MainApp < Gtk::Window
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
class ButtonPanel < Gtk::HButtonBox
|
|
45
|
-
attr_reader :
|
|
46
|
+
attr_reader :extract_button, :open_button
|
|
47
|
+
|
|
46
48
|
def initialize
|
|
47
49
|
super
|
|
48
50
|
set_layout(Gtk::BUTTONBOX_START)
|
|
@@ -72,7 +74,7 @@ class MainApp < Gtk::Window
|
|
|
72
74
|
@zipfile.each do |entry|
|
|
73
75
|
@clist.append([entry.name,
|
|
74
76
|
entry.size.to_s,
|
|
75
|
-
|
|
77
|
+
"#{100.0 * entry.compressedSize / entry.size}%"])
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
end
|
data/samples/qtzip.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$VERBOSE = true
|
|
4
5
|
|
|
@@ -6,14 +7,14 @@ $LOAD_PATH << '../lib'
|
|
|
6
7
|
|
|
7
8
|
require 'Qt'
|
|
8
9
|
system('rbuic -o zipdialogui.rb zipdialogui.ui')
|
|
9
|
-
require 'zipdialogui
|
|
10
|
+
require 'zipdialogui'
|
|
10
11
|
require 'zip'
|
|
11
12
|
|
|
12
13
|
a = Qt::Application.new(ARGV)
|
|
13
14
|
|
|
14
15
|
class ZipDialog < ZipDialogUI
|
|
15
16
|
def initialize
|
|
16
|
-
super
|
|
17
|
+
super
|
|
17
18
|
connect(child('add_button'), SIGNAL('clicked()'),
|
|
18
19
|
self, SLOT('add_files()'))
|
|
19
20
|
connect(child('extract_button'), SIGNAL('clicked()'),
|
|
@@ -65,14 +66,14 @@ class ZipDialog < ZipDialogUI
|
|
|
65
66
|
end
|
|
66
67
|
puts "selected_items.size = #{selected_items.size}"
|
|
67
68
|
puts "unselected_items.size = #{unselected_items.size}"
|
|
68
|
-
items =
|
|
69
|
+
items = selected_items.empty? ? unselected_items : selected_items
|
|
69
70
|
puts "items.size = #{items.size}"
|
|
70
71
|
|
|
71
72
|
d = Qt::FileDialog.get_existing_directory(nil, self)
|
|
72
|
-
if
|
|
73
|
-
puts 'No directory chosen'
|
|
74
|
-
else
|
|
73
|
+
if d
|
|
75
74
|
zipfile { |zf| items.each { |e| zf.extract(e, File.join(d, e)) } }
|
|
75
|
+
else
|
|
76
|
+
puts 'No directory chosen'
|
|
76
77
|
end
|
|
77
78
|
end
|
|
78
79
|
|
data/samples/write_simple.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
5
6
|
require 'zip'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Zip::OutputStream.open('simple.zip') do |zos|
|
|
8
9
|
zos.put_next_entry 'entry.txt'
|
|
9
10
|
zos.puts 'Hello world'
|
|
10
11
|
end
|