【问题标题】:Is it possible to use System.IO.Packaging.Package to zip a folder and add files/folders later to it?是否可以使用 System.IO.Packaging.Package 压缩文件夹并稍后添加文件/文件夹?
【发布时间】:2010-10-26 11:52:24
【问题描述】:

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

[编辑]

如果可能,我正在尝试使用本机 .net 库

【问题讨论】:

  • 您想专门使用 Package 类还是可以使用第三方库?
  • 如果可能,我正在尝试使用本机 .net 库。

标签: c# zip


【解决方案1】:

Native 库不是一个纯粹的 zipper,虽然它可以用来归档文件。它会在您的 zip 根目录中添加额外的文件。如果您不介意这个额外的文件,请使用它。还有其他库,它们以正确的方式归档,更快、更容易使用,并且具有矿石功能:DotNetZipSharpZipLib

【讨论】:

    【解决方案2】:

    Package 类用于处理包,它使用 zip 格式进行存储,但 zip 中包含特殊的元文件。一个包是一个 zip,但所有的 zip 文件都不是包。您只能使用 Package 类打开包,不能使用任何 zip 文件。

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

    【讨论】:

      【解决方案3】:

      您可以使用 .NET 仍支持的 J# 库提供的本机 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();
      }
      

      【讨论】:

        【解决方案4】:

        基于http://weblogs.asp.net/albertpascual/archive/2009/05/18/creating-a-folder-inside-the-zip-file-with-system-io-packaging.aspx

        这是我开发的,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
        

        【讨论】:

        • 感谢您的回答!不过,我已经标记了 C#。
        【解决方案5】:

        可以使用纯 .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 中。

        来源: 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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-07-20
          • 1970-01-01
          • 2010-09-05
          • 2012-06-19
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          相关资源
          最近更新 更多