8000 Add Ability to write Zip File to Buffer instead of File Stream. by dwhenry · Pull Request #2 · rubyzip/rubyzip · GitHub
[go: up one dir, main page]

Skip to content

Add Ability to write Zip File to Buffer instead of File Stream. #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
1 commit merged into from
Jan 7, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ test/okToDeleteMoved.txt
test/output.zip
test/test_putOnClosedStream.zip
test/zipWithDirs_copy.zip
nbproject/*
50 changes: 46 additions & 4 deletions lib/zip/zip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -944,10 +944,14 @@ class ZipOutputStream

# Opens the indicated zip file. If a file with that name already
# exists it will be overwritten.
def initialize(fileName)
def initialize(fileName, stream=false)
super()
@fileName = fileName
@outputStream = File.new(@fileName, "wb")
if stream
@outputStream = StringIO.new
else
@outputStream = File.new(@fileName, "wb")
end
@entrySet = ZipEntrySet.new
@compressor = NullCompressor.instance
@closed = false
Expand All @@ -966,6 +970,13 @@ def ZipOutputStream.open(fileName)
zos.close if zos
end

# Same as #open but writes to a filestream instead
def ZipOutputStream.write_buffer
zos = new('', true)
yield zos
return zos.close_buffer
end

# Closes the stream and writes the central directory to the zip file
def close
return if @closed
Expand All @@ -976,6 +987,16 @@ def close
@closed = true
end

# Closes the stream and writes the central directory to the zip file
def close_buffer
return @outputStream if @closed
finalize_current_entry
update_local_headers
write_central_directory
@closed = true
return @outputStream
end

# Closes the current entry and opens a new for writing.
# +entry+ can be a ZipEntry object or a string.
def put_next_entry(entryname, comment = nil, extra = nil, compression_method = ZipEntry::DEFLATED, level = Zlib::DEFAULT_COMPRESSION)
Expand Down Expand Up @@ -1385,11 +1406,11 @@ class ZipFile < ZipCentralDirectory

# Opens a zip archive. Pass true as the second parameter to create
# a new archive if it doesn't exist already.
def initialize(fileName, create = nil)
def initialize(fileName, create = nil, buffer = false)
super()
@name = fileName
@comment = ""
if (File.exists?(fileName))
if (File.exists?(fileName)) and !buffer
File.open(name, "rb") { |f| read_from_stream(f) }
elsif (create)
@entrySet = ZipEntrySet.new
Expand Down Expand Up @@ -1420,6 +1441,17 @@ def ZipFile.open(fileName, create = nil)
end
end

# Same as #open. But outputs data to a buffer instead of a file
def ZipFile.add_buffer
zf = ZipFile.new('', true, true)
begin
yield zf
ensure
buffer = zf.write_buffer
return buffer
end
end

# Returns the zip files comment, if it has one
attr_accessor :comment

Expand Down Expand Up @@ -1521,6 +1553,16 @@ def commit
initialize(name)
end

# Write buffer write changes to buffer and return
def write_buffer
buffer = ZipOutputStream.write_buffer do |zos|
@entrySet.each { |e| e.write_to_zip_output_stream(zos) }
zos.comment = comment
end
return buffer
end


# Closes the zip file committing any changes that has been made.
def close
commit
Expand Down
42 changes: 42 additions & 0 deletions test/ziptest.rb
C216
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,16 @@ def test_open
assert_test_zip_contents(TEST_ZIP)
end

def test_write_buffer
buffer = ZipOutputStream.write_buffer {
|zos|
zos.comment = TEST_ZIP.comment
write_test_zip(zos)
}
File.open(TEST_ZIP.zip_name, 'w') { |f| f.write buffer.string }
assert_test_zip_contents(TEST_ZIP)
end

def test_writingToClosedStream
assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
Expand Down Expand Up @@ -1041,6 +1051,23 @@ def setup
class ZipFileTest < Test::Unit::TestCase
include CommonZipFileFixture

def test_createFromScratchToBuffer
comment = "a short comment"

buffer = ZipFile.add_buffer do |zf|
zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
zf.mkdir("dir1")
zf.comment = comment
end

File.open(EMPTY_FILENAME, 'w') { |file| file.write buffer.string }
`cp #{EMPTY_FILENAME} ~/test.zip`

zfRead = ZipFile.new(EMPTY_FILENAME)
assert_equal(comment, zfRead.comment)
assert_equal(2, zfRead.entries.length)
end

def test_createFromScratch
comment = "a short comment"

Expand Down Expand Up @@ -1288,6 +1315,21 @@ def test_commit
zf.close
end

def test_write_buffer
newName = "renamedFirst"
zf = ZipFile.new(TEST_ZIP.zip_name)
oldName = zf.entries.first
zf.rename(oldName, newName)
buffer = zf.write_buffer
File.open(TEST_ZIP.zip_name, 'w') { |f| f.write buffer.string }
zfRead = ZipFile.new(TEST_ZIP.zip_name)
assert(zfRead.entries.detect { |e| e.name == newName } != nil)
assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
zfRead.close

zf.close
end

# This test tests that after commit, you
# can delete the file you used to add the entry to the zip file
# with
Expand Down
0