Reading Files in a Zip Archive, Without Unzipping The Archive

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:

  1. Open ZipFile1.zip
  2. Find the entry for ZipFile2.zip
  3. Open ZipFile2.zip as a Stream
  4. Create a new ZipFile object around nestedZipStream.
  5. Find the entry for file.txt
  6. Create a StreamReader around fileStream to read the text file.
  7. Read the contents of file.txt and output it to the console.

Try it online - in this sample, the base64 data is the binary data of a zip file which contains "test.zip", which in turn contains "file.txt". The contents of that text file is "hello".

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



Leave a reply



Submit