如何在vb.net 2.0中压缩文件夹及其子文件夹?

时间:2016-05-02 11:43:04

标签: vb.net vb.net-2010

我有Main1名称的文件夹。在那个文件夹里面,我有多个文件夹。喜欢

Folders1
Folders2
Folders3
Folders4

每个文件夹都有自己的文件。我的要求是压缩“Main1”文件夹,包括所有子文件夹及其文件。

我不想使用任何第三方工具。我打算使用Gzip命名空间System.Compression。请各位建议。

2 个答案:

答案 0 :(得分:3)

ZipFile.CreateFromDirectory()可以轻松为您完成此操作。只需将其传递给Day1文件夹的路径,它就会将整个文件夹压缩为zip文件。您可以使用System.IO.Directory类迭代所有Day文件夹。

(刚才意识到你想坚持使用.NET Fx 2.0。在那个版本中没有直接的方法。你必须使用你不想要的第三方库,或者做低级别的东西)。

修改

如果你真的倾向于手工做,这是一种粗暴的方式:

  1. 获取Day目录中所有目录的列表(递归);称之为DirList
  2. 获取Day目录中所有文件的列表(递归);称之为FilesList
  3. 创建Dictionary(Of String, String)并将FilesList中每个文件的名称及其内容的BASE64表示存储起来;名称为Key,内容为Value。
  4. 使用.NET的内置XML序列化将词典保存到XML文件。
  5. 在文件的最开头,注入DirList
  6. 的内容
  7. 再次保存文件。 (你也可以一步完成第4-6步)。
  8. 将此文件读取为二进制文件,并使用GZip压缩整个内容。
  9. 将其写入zip文件。
  10. 要解压缩此文件:

    1. 打开文件并使用GZip解压缩并获取整个内容。
    2. 从顶部抓取目录列表并以递归方式创建所有目录。
    3. 完整阅读其余部分,并使用XML序列化从中创建Dictionary对象。
    4. 遍历Dictionary并使用Key部分创建文件,然后通过将其值从BASE64转换回二进制文件将内容注入文件。
    5. 如果您对这些步骤有任何疑问,请与我们联系。

      编辑2

      以下代码是针对.NET 2.0编译的,它将压缩和解压缩目录:

      Public Function ZipDirectory(DirPath As String) As Byte()
          If Not Directory.Exists(DirPath) Then Return Nothing
      
          Dim Directories = Directory.GetDirectories(DirPath, "*", SearchOption.AllDirectories)
          Dim Files = Directory.GetFiles(DirPath, "*", SearchOption.AllDirectories)
      
          Dim X As New XmlDocument
          Dim RootNode = X.CreateElement("Content")
          Dim DirsNode = X.CreateElement("Directories")
          Dim FilesNode = X.CreateElement("Directories")
      
          X.AppendChild(RootNode)
          RootNode.AppendChild(DirsNode)
          RootNode.AppendChild(FilesNode)
      
          For Each d In Directories
            Dim DirNode = X.CreateElement("Directory")
            Dim PathAttrib = X.CreateAttribute("Path")
            PathAttrib.Value = d.Replace(DirPath & "\", "") 'Create relative paths
            DirNode.Attributes.Append(PathAttrib)
            DirsNode.AppendChild(DirNode)
          Next
      
          For Each f In Files
            Dim FileNode = X.CreateElement("File")
            Dim PathAttrib = X.CreateAttribute("Path")
            PathAttrib.Value = f.Replace(DirPath & "\", "") 'Create relative paths
            FileNode.Attributes.Append(PathAttrib)
            FileNode.InnerText = Convert.ToBase64String(File.ReadAllBytes(f))
            FilesNode.AppendChild(FileNode)
          Next
      
          Using Mem As New MemoryStream()
            X.Save(Mem)
            Dim AllContentsAsByteArray = Mem.ToArray()
            Dim CompressedContent = CompressArray(AllContentsAsByteArray)
            Return CompressedContent
          End Using
        End Function
      
        Public Sub UnzipDirectory(compressed() As Byte, outputPath As String)
          If Not Directory.Exists(outputPath) Then Directory.CreateDirectory(outputPath)
      
          Dim Uncompressed = DecompressArray(Compressed)
      
          Dim X As New XmlDocument
      
          Using Mem As New MemoryStream(Uncompressed)
            X.Load(Mem)
      
            Dim RootNode = X.FirstChild
            Dim DirsNode = RootNode.FirstChild
            Dim FilesNode = RootNode.FirstChild.NextSibling
      
            For Each ChildDir In DirsNode.ChildNodes
              Directory.CreateDirectory(Path.Combine(outputPath, DirectCast(ChildDir, XmlNode).Attributes.Item(0).Value))
            Next
      
            For Each ChildFile In FilesNode.ChildNodes
              Dim FilePath = Path.Combine(outputPath, DirectCast(ChildFile, XmlNode).Attributes.Item(0).Value)
              Dim Content = Convert.FromBase64String(DirectCast(ChildFile, XmlNode).InnerText)
              File.WriteAllBytes(FilePath, Content)
            Next
          End Using
        End Sub
      
        Private Function CompressArray(ByVal content() As Byte) As Byte()
          Using outFile As New MemoryStream()
            Using Compress As New GZipStream(outFile, CompressionMode.Compress)
              Compress.Write(content, 0, content.Length)
            End Using
      
            Return outFile.ToArray()
          End Using
        End Function
      
        Private Function DecompressArray(ByVal content() As Byte) As Byte()
          Using outFile As New MemoryStream()
            Using inFile As New MemoryStream(content)
              Using Compress As New GZipStream(inFile, CompressionMode.Decompress)
                Dim buffer(1023) As Byte
                Dim nRead As Integer
                Do
                  nRead = Compress.Read(buffer, 0, buffer.Length)
                  outFile.Write(buffer, 0, nRead)
                Loop While nRead > 0
              End Using
            End Using
      
            Return outFile.ToArray()
          End Using
        End Function
      

      代码应该像这样使用:

      'To zip a directory
      Dim Compressed = ZipDirectory("C:\SomeDir") 
      File.WriteAllBytes("C:\somedir.zip", Compressed)
      
      'To unzip a zipped file
      Dim Compressed = File.ReadAllBytes("C:\somedir.zip") 
      UnzipDirectory(Compressed, "C:\SomeDir2")
      

答案 1 :(得分:1)

以下代码使用System.IO.Compression

来自MSDN网站的示例:

Link

Imports System
Imports System.Collections.Generic
imports System.IO
imports System.IO.Compression

Public Class CompressionSnippet

    Public Shared Sub Main()
        Dim path As String = "test.txt"

        ' Create the text file if it doesn't already exist.
        If Not File.Exists(path) Then
            Console.WriteLine("Creating a new test.txt file")
            Dim text() As String = {"This is a test text file.", _
                "This file will be compressed and written to the disk.", _
                "Once the file is written, it can be decompressed", _
                "imports various compression tools.", _
                "The GZipStream and DeflateStream class use the same", _
                "compression algorithms, the primary difference is that", _
                "the GZipStream class includes a cyclic redundancy check", _
                "that can be useful for detecting data corruption.", _
                "One other side note: both the GZipStream and DeflateStream", _
                "classes operate on streams as opposed to file-based", _
                "compression data is read on a byte-by-byte basis, so it", _
                "is not possible to perform multiple passes to determine the", _
                "best compression method. Already compressed data can actually", _
                "increase in size if compressed with these classes."}

            File.WriteAllLines(path, text)
        End If

        Console.WriteLine("Contents of {0}", path)
        Console.WriteLine(File.ReadAllText(path))

        CompressFile(path)
        Console.WriteLine()

        UncompressFile(path + ".gz")
        Console.WriteLine()

        Console.WriteLine("Contents of {0}", path + ".gz.txt")
        Console.WriteLine(File.ReadAllText(path + ".gz.txt"))

    End Sub

    Public Shared Sub CompressFile(ByVal path As String)
        Dim sourceFile As FileStream = File.OpenRead(path)
        Dim destinationFile As FileStream = File.Create(path + ".gz")

        Dim buffer(sourceFile.Length) As Byte
        sourceFile.Read(Buffer, 0, Buffer.Length)

        Using output As New GZipStream(destinationFile, _
            CompressionMode.Compress)

            Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name, _
                destinationFile.Name, False)

            output.Write(buffer, 0, buffer.Length)
        End Using

        ' Close the files.
        sourceFile.Close()
        destinationFile.Close()
    End Sub

    Public Shared Sub UncompressFile(ByVal path As String)
        Dim sourceFile As FileStream = File.OpenRead(path)
        Dim destinationFile As FileStream = File.Create(path + ".txt")

        ' Because the uncompressed size of the file is unknown, 
        ' we are imports an arbitrary buffer size.
        Dim buffer(4096) As Byte
        Dim n As Integer

        Using input As New GZipStream(sourceFile, _
            CompressionMode.Decompress, False)

            Console.WriteLine("Decompressing {0} to {1}.", sourceFile.Name, _
                destinationFile.Name)

            n = input.Read(buffer, 0, buffer.Length)
            destinationFile.Write(buffer, 0, n)
        End Using

        ' Close the files.
        sourceFile.Close()
        destinationFile.Close()
    End Sub
End Class

真的,你最好不要使用SharpLibZip