C# 是否可以使用System.IO.Packaging.Package压缩文件夹并在以后向其中添加文件/文件夹?

C# 是否可以使用System.IO.Packaging.Package压缩文件夹并在以后向其中添加文件/文件夹?,c#,zip,C#,Zip,我想知道我们是否可以使用将文件夹压缩为文件.zip文件。然后,我要打开file.zip,并向其中添加更多文件/文件夹。可能吗 [编辑] 如果可能的话,我正在尝试使用本机.net库包类用于处理包,它使用zip格式存储,但zip中包含特殊的元文件。包是一个zip文件,但所有zip文件都不是包。只能使用package类打开包,而不能使用任何zip文件 public void AddFileToZip(string zipFilename, string fileToAdd, string destDi

我想知道我们是否可以使用将文件夹压缩为
文件.zip
文件。然后,我要打开
file.zip
,并向其中添加更多文件/文件夹。可能吗

[编辑]


如果可能的话,我正在尝试使用本机.net库包
类用于处理包,它使用zip格式存储,但zip中包含特殊的元文件。包是一个zip文件,但所有zip文件都不是包。只能使用
package
类打开包,而不能使用任何zip文件

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);
            }
        }
    }
}

第三方库可能更好,因为您不局限于包的形式。

本机库不是一个纯粹的拉链,尽管它可以用来归档文件。它会在zip的根目录中添加额外的文件。如果你不介意这个额外的文件,那么就使用它。还有其他一些库,它们以正确的方式进行归档,并且更快、更易于使用,并且具有ore功能:和。

您可以使用.NET中仍然支持的J#library提供的本机Zip类-您必须在项目中添加对
vjslib
的引用才能启用这些类

示例代码:

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();
}
基于

以下是我开发的2个签名,您可以在zip文件中创建目录:

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
Imports System.IO
导入System.IO打包
公共类压缩
常量缓冲区大小(长=4096)
次新
端接头
公共函数AddFileToZip(ByVal zipFilename作为字符串_
ByVal文件添加为字符串_
ByVal directoryFile(作为字符串)作为布尔值
将跟踪变暗为字符串=“”
尝试
trace=String.Format(“{0}AddFileToZip-zipFilename:'{1}'文件添加:'{2}'{3}”_
现在,zipFilename、fileToAdd、vbNewLine)
使用zip作为Package=System.IO.Packaging.Package.Open(zipFilename、FileMode.OpenOrCreate)
Dim destFilename为String=“.\”&directoryFile&“\”&Path.GetFileName(fileToAdd)
Dim uri As uri=PackUriHelper.CreatePartUri(新uri(destFilename,UriKind.Relative))
如果zip.PartExists(uri)那么
zip.DeletePart(uri)
如果结束
作为PackagePart=zip.CreatePart(uri,“,CompressionOption.Normal)的Dim部件
将fileStream用作新的fileStream(fileToAdd、FileMode.Open、FileAccess.Read)
使用dest作为Stream=part.GetStream()
CopyStream(文件流,目的地)
终端使用
终端使用
终端使用
返回真值
特例
返回错误
结束尝试
端函数
作为布尔值的公共函数AddFileToZip(ByVal zipFilename作为字符串,ByVal fileToAdd作为字符串)
将跟踪变暗为字符串=“”
尝试
trace=String.Format(“{0}AddFileToZip-zipFilename:'{1}'文件添加:'{2}'{3}”_
现在,zipFilename、fileToAdd、vbNewLine)
使用zip作为Package=System.IO.Packaging.Package.Open(zipFilename、FileMode.OpenOrCreate)
Dim destFilename As String=“.\”&Path.GetFileName(fileToAdd)
Dim uri As uri=PackUriHelper.CreatePartUri(新uri(destFilename,UriKind.Relative))
如果zip.PartExists(uri)那么
zip.DeletePart(uri)
如果结束
作为PackagePart=zip.CreatePart(uri,“,CompressionOption.Normal)的Dim部件
将fileStream用作新的fileStream(fileToAdd、FileMode.Open、FileAccess.Read)
使用dest作为Stream=part.GetStream()
CopyStream(文件流,目的地)
终端使用
终端使用
终端使用
返回真值
特例
返回错误
结束尝试
端函数
私有子CopyStream(ByVal inputStream作为System.IO.FileStream,ByVal outputStream作为System.IO.Stream)
Dim bufferSize As Long=If(inputStream.Length<缓冲区大小,inputStream.Length,缓冲区大小)
Dim buffer As Byte()=新字节(CInt(bufferSize)-1){}
Dim字节读取为整数=0
Dim字节写入为Long=0
而(InlineAssignHelper(bytesRead,inputStream.Read(buffer,0,buffer.Length)))0
outputStream.Write(缓冲区,0,字节读取)
字节写入+=缓冲区大小
结束时
端接头
InlineAssignHelper(Of T)中的私有函数(ByRef目标为T,ByVal值为T)为T
目标=价值
返回值
端函数
末级

这可以用纯.NET 3.0来完成。由于修改了GPL许可证,使用SharpZipLib可能不可取

首先,您需要对WindowsBase.dll的引用

这段代码将打开或创建一个zip文件,在其中创建一个目录,并将文件放在该目录中。如果要压缩文件夹(可能包含子目录),可以循环目录中的文件,并为每个文件调用此方法。然后,您可以先在子目录中搜索文件,为每个子目录调用方法,然后传入路径以在zip文件中创建层次结构

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可以是一个空字符串,它将文件直接放在zip中

资料来源:


您想专门使用Package类还是可以使用第三方库?如果可能,我正在尝试使用本机.net库。谢谢您的回答!不过,我已经标记了C。