@@ -64,24 +64,38 @@ class File < CentralDirectory
64
64
65
65
# Opens a zip archive. Pass true as the second parameter to create
66
66
# a new archive if it doesn't exist already.
67
- def initialize ( file_name , create = false , buffer = false , options = { } )
67
+ def initialize ( path_or_io , create = false , buffer = false , options = { } )
68
68
super ( )
69
- @name = file_name
69
+ @name = path_or_io . respond_to? ( :path ) ? path_or_io . path : path_or_io
70
70
@comment = ''
71
71
@create = create ? true : false # allow any truthy value to mean true
72
- if !buffer && ::File . size? ( file_name )
72
+
73
+ if ::File . size? ( @name . to_s )
74
+ # There is a file, which exists, that is associated with this zip.
73
75
@create = false
74
- @file_permissions = ::File . stat ( file_name ) . mode
75
- ::File . open ( name , 'rb' ) do |f |
76
- read_from_stream ( f )
76
+ @file_permissions = ::File . stat ( @name ) . mode
77
+
78
+ if buffer
79
+ read_from_stream ( path_or_io )
80
+ else
81
+ ::File . open ( @name , 'rb' ) do |f |
82
+ read_from_stream ( f )
83
+ end
77
84
end
85
+ elsif buffer && path_or_io . size > 0
86
+ # This zip is probably a non-empty StringIO.
87
+ read_from_stream ( path_or_io )
78
88
elsif @create
89
+ # This zip is completely new/empty and is to be created.
79
90
@entry_set = EntrySet . new
80
- elsif ::File . zero? ( file_name )
81
- raise Error , "File #{ file_name } has zero size. Did you mean to pass the create flag?"
91
+ elsif ::File . zero? ( @name )
92
+ # A file exists, but it is empty.
93
+ raise Error , "File #{ @name } has zero size. Did you mean to pass the create flag?"
82
94
else
83
- raise Error , "File #{ file_name } not found"
95
+ # Everything is wrong.
96
+ raise Error , "File #{ @name } not found"
84
97
end
98
+
85
99
@stored_entries = @entry_set . dup
86
100
@stored_comment = @comment
87
101
@restore_ownership = options [ :restore_ownership ] || false
@@ -119,17 +133,16 @@ def open_buffer(io, options = {})
119
133
unless IO_METHODS . map { |method | io . respond_to? ( method ) } . all? || io . is_a? ( String )
120
134
raise "Zip::File.open_buffer expects a String or IO-like argument (responds to #{ IO_METHODS . join ( ', ' ) } ). Found: #{ io . class } "
121
135
end
122
- if io . is_a? ( ::String )
123
- require 'stringio'
124
- io = ::StringIO . new ( io )
125
- elsif io . respond_to? ( :binmode )
126
- # https://github.com/rubyzip/rubyzip/issues/119
127
- io . binmode
128
- end
136
+
137
+ io = ::StringIO . new ( io ) if io . is_a? ( ::String )
138
+
139
+ # https://github.com/rubyzip/rubyzip/issues/119
140
+ io . binmode if io . respond_to? ( :binmode )
141
+
129
142
zf = ::Zip ::File . new ( io , true , true , options )
130
- zf . read_from_stream ( io )
131
143
return zf unless block_given?
132
144
yield zf
145
+
133
146
begin
134
147
zf . write_buffer ( io )
135
148
rescue IOError => e
0 commit comments