问题
How do you write a ZipFile
to disk using SharpZipLib?
- Do you have to open an output stream to write a
ZipFile
to disk? - Is there some way to just get the
ZipFile
bytes and doFile.WriteAllBytes()
?
Note: My question is not about compression. Just about taking an existing ZipFile
and writing it to disk.
Also, please note, I have already perused docs and this use case is not there.
https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples
回答1:
Do you have to open an output stream to write a ZipFile to disk?
According to their Github samples, they are suggesting to create a stream object using ZipOutputStream
to write the file and to write into the file being zipped, you need to open a FileStream
to write the objects into the library.
Here is the sample of the code that you can use to zip files.
// Depending on the directory this could be very large and would require more attention
// in a commercial package.
string[] filenames = Directory.GetFiles("directory");
// 'using' statements guarantee the stream is closed properly which is a big source
// of problems otherwise. Its exception safe as well which is great.
using (ZipOutputStream s = new ZipOutputStream(File.Create("outputfile")))
{
s.SetLevel(9); // 0 - store only to 9 - means best compression
byte[] buffer = new byte[4096];
foreach (string file in filenames)
{
// Using GetFileName makes the result compatible with XP
// as the resulting path is not absolute.
var entry = new ZipEntry(Path.GetFileName(file));
// Setup the entry data as required.
// Crc and size are handled by the library for seakable streams
// so no need to do them here.
// Could also use the last write time or similar for the file.
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
using (FileStream fs = File.OpenRead(file))
{
// Using a fixed size buffer here makes no noticeable difference for output
// but keeps a lid on memory usage.
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}
// Finish/Close arent needed strictly as the using statement does this automatically
// Finish is important to ensure trailing information for a Zip file is appended. Without this
// the created file would be invalid.
s.Finish();
// Close is important to wrap things up and unlock the file.
s.Close();
}
Is there some way to just get the ZipFile bytes and do File.WriteAllBytes()?
If you are asking if we can write bytes of the files directly without opening the FileStream
to read the files that are to be written in the zip file, then, Yes, you can write all bytes at once into the source zip file but that is a bad way as it will read all the bytes at once into the memory and this could be disastrous if the files being zipped are huge in size. Anyways, here is how you can do it:
Just replace the FileStream
part in the above sample with this code:
var bytes = File.ReadAllBytes(file);
s.Write(bytes, 0, bytes.Length); // write all bytes from 0 to the length of the bytes
So, the updated source code would be:
string[] filenames = Directory.GetFiles("directory");
using (ZipOutputStream s = new ZipOutputStream(File.Create("outputfile")))
{
s.SetLevel(9);
byte[] buffer = new byte[4096];
foreach (string file in filenames)
{
var entry = new ZipEntry(Path.GetFileName(file));
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
var bytes = File.ReadAllBytes(file);
s.Write(bytes, 0, bytes.Length);
}
s.Finish();
s.Close();
}
来源:https://stackoverflow.com/questions/64654189/how-do-you-write-a-zipfile-to-disk-using-sharpziplib