Is it possible to use System.IO.Packaging.Package to zip a folder and add files/folders later to it?
I wonder if we can use the .net class ZipPackage to zip a folder to a file.zip
file. And then开发者_运维问答, I want open file.zip
and add more files/folders into it. Is it possible?
[Edit]
I'm trying to use native .net library if possible
Native library is not a pure zipper, though it can be used to archive files. It adds extra file in your zip's root. If you don't mind this extra file then use it. There are other libraries, that do archiving the proper way, and are faster, easier to use, and with ore features: DotNetZip and SharpZipLib.
The Package
class is used to handle packages, which uses the zip format for storage, but has special meta files included in the zip. A package is a zip, but all zip files aren't packages. You can only open a package using the Package
class, not any zip file.
A third party library would probably be better, as you are not restricted to the form of a package.
You can use the native Zip classes provided by the J# library still supported in .NET - you do have to add a reference to vjslib
to your project to enable these.
Sample code:
using java.io;
using java.util.zip;
...
private void ZipFile(string sourceFile, string targetName, ref ZipOutputStream zipout)
{
// read the temporary file to a file source
java.io.FileInputStream fileSourceInputStream = new java.io.FileInputStream(sourceFile);
// create a zip entry
ZipEntry ze = new ZipEntry(targetName);
ze.setMethod(ZipEntry.DEFLATED);
zipout.putNextEntry(ze);
// stream the file to the zip
CopyStream(fileSourceInputStream, zipout);
zipout.closeEntry();
// flush all data to the zip
fileSourceInputStream.close();
zipout.flush();
}
private static void CopyStream(java.io.InputStream from, java.io.OutputStream to)
{
BufferedInputStream input = new BufferedInputStream(from);
BufferedOutputStream output = new BufferedOutputStream(to);
sbyte[] buffer = new sbyte[16384];
int got;
while ((got = input.read(buffer, 0, buffer.Length)) > 0)
{
output.write(buffer, 0, got);
}
output.flush();
}
Based on http://weblogs.asp.net/albertpascual/archive/2009/05/18/creating-a-folder-inside-the-zip-file-with-system-io-packaging.aspx
Here's what I developped, 2 signatures, so you can create directories in your zip file :
Imports System.IO
Imports System.IO.Packaging
Public Class clsCompression
Const BUFFER_SIZE As Long = 4096
Sub New()
End Sub
Public Function AddFileToZip(ByVal zipFilename As String, _
ByVal fileToAdd As String, _
ByVal directoryFile As String) As Boolean
Dim trace As String = ""
Try
trace = String.Format("{0} AddFileToZip zipFilename: '{1}' fileToAdd: '{2}'{3}", _
Now, zipFilename, fileToAdd, vbNewLine)
Using zip As Package = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate)
Dim destFilename As String = ".\" & directoryFile & "\" & Path.GetFileName(fileToAdd)
Dim uri As Uri = PackUriHelper.CreatePartUri(New Uri(destFilename, UriKind.Relative))
If zip.PartExists(uri) Then
zip.DeletePart(uri)
End If
Dim part As PackagePart = zip.CreatePart(uri, "", CompressionOption.Normal)
Using fileStream As New FileStream(fileToAdd, FileMode.Open, FileAccess.Read)
Using dest As Stream = part.GetStream()
CopyStream(fileStream, dest)
End Using
End Using
End Using
Return True
Catch ex As Exception
Return False
End Try
End Function
Public Function AddFileToZip(ByVal zipFilename As String, ByVal fileToAdd As String) As Boolean
Dim trace As String = ""
Try
trace = String.Format("{0} AddFileToZip zipFilename: '{1}' fileToAdd: '{2}'{3}", _
Now, zipFilename, fileToAdd, vbNewLine)
Using zip As Package = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate)
Dim destFilename As String = ".\" & Path.GetFileName(fileToAdd)
Dim uri As Uri = PackUriHelper.CreatePartUri(New Uri(destFilename, UriKind.Relative))
If zip.PartExists(uri) Then
zip.DeletePart(uri)
End If
Dim part As PackagePart = zip.CreatePart(uri, "", CompressionOption.Normal)
Using fileStream As New FileStream(fileToAdd, FileMode.Open, FileAccess.Read)
Using dest As Stream = part.GetStream()
CopyStream(fileStream, dest)
End Using
End Using
End Using
Return True
Catch ex As Exception
Return False
End Try
End Function
Private Sub CopyStream(ByVal inputStream As System.IO.FileStream, ByVal outputStream As System.IO.Stream)
Dim bufferSize As Long = If(inputStream.Length < BUFFER_SIZE, inputStream.Length, BUFFER_SIZE)
Dim buffer As Byte() = New Byte(CInt(bufferSize) - 1) {}
Dim bytesRead As Integer = 0
Dim bytesWritten As Long = 0
While (InlineAssignHelper(bytesRead, inputStream.Read(buffer, 0, buffer.Length))) <> 0
outputStream.Write(buffer, 0, bytesRead)
bytesWritten += bufferSize
End While
End Sub
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
End Class
It can be done with pure .NET 3.0. Using SharpZipLib may not be desirable due to the modified GPL license.
First, you will need a reference to WindowsBase.dll.
This code will open or create a zip file, create a directory inside, and place the file in that directory. If you want to zip a folder, possibly containing sub-directories, you could loop through the files in the directory and call this method for each file. Then, you could depth-first search the sub-directories for files, call the method for each of those and pass in the path to create that hierarchy within the zip file.
public void AddFileToZip(string zipFilename, string fileToAdd, string destDir)
{
using (Package zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
{
string destFilename = "." + destDir + "\\" + Path.GetFileName(fileToAdd);
Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
if (zip.PartExists(uri))
{
zip.DeletePart(uri);
}
PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal);
using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
{
using (Stream dest = part.GetStream())
{
CopyStream(fileStream, dest);
}
}
}
}
destDir could be an empty string, which would place the file directly in the zip.
Sources: https://weblogs.asp.net/jongalloway/creating-zip-archives-in-net-without-an-external-library-like-sharpziplib
https://weblogs.asp.net/albertpascual/creating-a-folder-inside-the-zip-file-with-system-io-packaging
精彩评论