Reading files in a zip archive, without unzipping the archive
The Zip::NullInputStream
is returned if the entry is a directory and not a file, could that be the case?
Here's a more robust variation of the code:
#!/usr/bin/env ruby
require 'rubygems'
require 'zip'
Zip::File.open('my_zip.zip') do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
if entry.directory?
puts "#{entry.name} is a folder!"
elsif entry.symlink?
puts "#{entry.name} is a symlink!"
elsif entry.file?
puts "#{entry.name} is a regular file!"
# Read into memory
entry.get_input_stream { |io| content = io.read }
# Output
puts content
else
puts "#{entry.name} is something unknown, oops!"
end
end
end
Trying to read files in a zip archive without extracting them
According to the rubyzip documentation (and the question you linked) mZip
should be of class String
and contain the path to a file rather than File
or Zip::Entry
.
mZip = './folder/file.zip'
def read_file
Zip::File.open(myZip) do |zip_file|
#...
end
How to read data from a zip file without having to unzip the entire file
DotNetZip is your friend here.
As easy as:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
ZipEntry e = zip["MyReport.doc"];
e.Extract(OutputStream);
}
(you can also extract to a file or other destinations).Reading the zip file's table of contents is as easy as:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
foreach (ZipEntry e in zip)
{
if (header)
{
System.Console.WriteLine("Zipfile: {0}", zip.Name);
if ((zip.Comment != null) && (zip.Comment != ""))
System.Console.WriteLine("Comment: {0}", zip.Comment);
System.Console.WriteLine("\n{1,-22} {2,8} {3,5} {4,8} {5,3} {0}",
"Filename", "Modified", "Size", "Ratio", "Packed", "pw?");
System.Console.WriteLine(new System.String('-', 72));
header = false;
}
System.Console.WriteLine("{1,-22} {2,8} {3,5:F0}% {4,8} {5,3} {0}",
e.FileName,
e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
e.UncompressedSize,
e.CompressionRatio,
e.CompressedSize,
(e.UsesEncryption) ? "Y" : "N");
}
}
Edited To Note: DotNetZip used to live at Codeplex. Codeplex has been shut down. The old archive is still available at Codeplex. It looks like the code has migrated to Github:
- https://github.com/DinoChiesa/DotNetZip. Looks to be the original author's repo.
- https://github.com/haf/DotNetZip.Semverd. This looks to be the currently maintained version. It's also packaged up an available via Nuget at https://www.nuget.org/packages/DotNetZip/
How to read data from inner archives without extracting zip file?
Based on this answer, you can open a file within the zip as a Stream
. You can also open a ZipFile
from a Stream
. I'm sure you can see where this is heading.
using (var zip = new ZipFile("ZipFile1.zip"))
{
var nestedZipEntry = zip.GetEntry("ZipFile2.zip");
using (var nestedZipStream = zip.GetInputStream(nestedZipEntry))
using (var nestedZip = new ZipFile(nestedZipStream))
{
var fileEntry = nestedZip.GetEntry("file.txt");
using (var fileStream = nestedZip.GetInputStream(fileEntry))
using (var reader = new StreamReader(fileStream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
What we're doing here:- Open ZipFile1.zip
- Find the entry for ZipFile2.zip
- Open ZipFile2.zip as a
Stream
- Create a new
ZipFile
object aroundnestedZipStream
. - Find the entry for file.txt
- Create a
StreamReader
aroundfileStream
to read the text file. - Read the contents of file.txt and output it to the console.
P.S. If an entry isn't found then GetEntry
will return null. You'll want to check for that in any code you write. It works here because I'm sure that these entries exist in their respective archives.
Python: Open file in zip without temporarily extracting it
Vincent Povirk's answer won't work completely;
import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgfile = archive.open('img_01.png')
...
You have to change it in:import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgdata = archive.read('img_01.png')
...
For details read the ZipFile
docs here. Is there a way to open files in a zip file without decompressing (c#)
i believe you can use the System.IO.Compression library...
Assembly: System.IO.Compression.ZipFile.dll
something like the following...
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
{
entry.ExtractToFile(destinationPath);
}
}
}
How to read file from ZIP archive to memory without extracting it to file first, by using C# .NET 4.5?
Adapted from the ZipArchive
and XmlSerializer.Deserialize()
manual pages.
The ZipArchiveEntry
class has an Open()
method, which returns a stream to the file.
string zipPath = @"c:\example\start.zip";
using (ZipArchive archive = ZipFile.OpenRead(zipPath))
{
var sample = archive.GetEntry("sample.xml");
if (sample != null)
{
using (var zipEntryStream = sample.Open())
{
XmlSerializer serializer = new XmlSerializer(typeof(SampleClass));
SampleClass deserialized =
(SampleClass)serializer.Deserialize(zipEntryStream);
}
}
}
Note that, as documented on MSDN, you need to add a reference to the .NET assembly System.IO.Compression.FileSystem
in order to use the ZipFile
class.
Related Topics
Rvm Can No Longer Install 1.8.7-P352 on MAC Os X Mountain Lion
Automatically Adding Proxy to All Http Connections in Ruby
Browsing Ruby Code a La Smalltalk
Can't Install Debugger Gem - Rails - MAC Osx Mavericks
Error Installing Rdoc Documentation: Incompatible Encoding Regexp Match
Regex to Check Alphanumeric String in Ruby
Easiest Way to Convert "A/B/C" to ["A/B/C", "A/B", "A"]
If I Have a Stripe Token from a Charge, How to Get Its Charge Id
Automatically Logging Exceptions in Ruby
Recommended Way to Generate a Presigned Url to S3 Bucket in Ruby
Get Route for Base Class of Sti Class in Rails
What Ruby Technique Does Rails Use to Make My Controller Methods Render Views
Rails Parameters from Get/Post
Rails Has_Many Through Form with Additional Attributes
How to Tell Unicorn to Understand Heroku's Signals
How to Access Sinatra App on Host Machine with Vagrant Forwarded Ports