C# - Sharpziplib - 提取sub zip,sub gz,sub tar.gz的内容

时间:2017-07-14 16:02:36

标签: c# sharpziplib

我是C#和面向对象编程的新手。我正在尝试创建一个应用程序来提取压缩文件的内容。

在搜索时,我发现.NET默认不支持gz或tar文件。这样就下载了SharpZipLib。我仔细阅读了上述例子。

以下是代码:

static void Main(string[] args)
{
    List<string> fileList = new List<string>();
    List<string> targzList = new List<string>();

    Console.WriteLine("Begin Extracting?");
    var ch = Console.ReadLine();
    if (ch == "y")
    {
        Console.WriteLine("Extracting The Zip {0}", zipFilePath);
        ExtractZipFile(zipFilePath, null, destinationPath);
        Console.WriteLine("Extraction Finished...");
        foreach (string file in Directory.GetFiles(destinationPath))
        {

            fileList.Add(file);
        }
    }
    Console.WriteLine("The following are the files in directory");
    foreach (string file in fileList)
    {
        Console.WriteLine(file);
    }

    Console.WriteLine("Extract All The Files?");
    var cht = Console.ReadLine();
    if (cht == "y")
    {
        foreach(var file in fileList)
        {
            if(Path.GetFileNameWithoutExtension(file).Contains("tar"))
            {
                targzList.Add(file);
                ExtractTGZ(file,Path.GetDirectoryName(file)+@"\"+Path.GetFileNameWithoutExtension(file));
            }
        }

    }



    Console.ReadLine();
}


public static void ExtractZipFile(string archiveFilenameIn, string password, string outFolder)
{
    ZipFile zf = null;
    try
    {
        FileStream fs = File.OpenRead(archiveFilenameIn);
        zf = new ZipFile(fs);
        if (!String.IsNullOrEmpty(password))
        {
            zf.Password = password;     // AES encrypted entries are handled automatically
        }
        foreach (ZipEntry zipEntry in zf)
        {
            if (!zipEntry.IsFile)
            {
                continue;           // Ignore directories
            }
            String entryFileName = zipEntry.Name;
            // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName);
            // Optionally match entrynames against a selection list here to skip as desired.
            // The unpacked length is available in the zipEntry.Size property.

            byte[] buffer = new byte[4096];     // 4K is optimum
            Stream zipStream = zf.GetInputStream(zipEntry);

            // Manipulate the output filename here as desired.
            String fullZipToPath = Path.Combine(outFolder, entryFileName);
            string directoryName = Path.GetDirectoryName(fullZipToPath);
            if (directoryName.Length > 0)
                Directory.CreateDirectory(directoryName);

            // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size
            // of the file, but does not waste memory.
            // The "using" will close the stream even if an exception occurs.
            using (FileStream streamWriter = File.Create(fullZipToPath))
            {
                StreamUtils.Copy(zipStream, streamWriter, buffer);
            }
        }
    }
    finally
    {
        if (zf != null)
        {
            zf.IsStreamOwner = true; // Makes close also shut the underlying stream
            zf.Close(); // Ensure we release resources
        }
    }
}

public static void ExtractTGZ(String gzArchiveName, String destFolder)
{

    Stream inStream = File.OpenRead(gzArchiveName);
    Stream gzipStream = new GZipInputStream(inStream);

    TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
    tarArchive.ExtractContents(destFolder);
    tarArchive.Close();

    gzipStream.Close();
    inStream.Close();
}

public static void ExtractGZip(string gzipFileName, string targetDir)
{

    // Use a 4K buffer. Any larger is a waste.    
    byte[] dataBuffer = new byte[4096];

    using (System.IO.Stream fs = new FileStream(gzipFileName, FileMode.Open, FileAccess.Read))
    {
        using (GZipInputStream gzipStream = new GZipInputStream(fs))
        {

            // Change this to your needs
            string fnOut = Path.Combine(targetDir, Path.GetFileNameWithoutExtension(gzipFileName));

            using (FileStream fsOut = File.Create(fnOut))
            {
                StreamUtils.Copy(gzipStream, fsOut, dataBuffer);
            }
        }
    }
}

该文件可以是zip,gz,tar或tar.gz文件。它可以包含多个zip或gz或tar.gz文件。要提取的压缩文件的所有内容,直到没有压缩文件留在任何目录或子目录中。

结构如下

foo.zip or foo.tar.gz
 ├───bar1.tar.gz
 │   ├───foobar1.tar
 │              ├───foobarr2.tar.gz
 ├───bar2.tar.gz
 │   ├───foobar2.tar
 │                  ├───foobarr2.zip
 ├───bar3.tar.gz
 │   ├───foobar3.tar
 ├───bar4.tar.gz
 │   ├───foobar4.tar
 ├───bar5.tar.gz
 │   ├───foobar5.tar
 ├───bar6.tar.gz
 │   ├───foobar6.tar
 |   ..........
 |   ..........
 |   ..........
 |   20+ of them

得到解决方案,检查我的答案。

由于

1 个答案:

答案 0 :(得分:0)

借助递归,我实现了目标。

 public static void FindFiles (string path)
        {
            foreach(string fileName in Directory.GetFiles(path))
            {

                if (Path.GetExtension(fileName) == ".zip")
                {
                    Console.WriteLine(fileName);

                    ExtractZipFile(fileName, null, Path.GetDirectoryName(fileName) + @"\" + Path.GetFileNameWithoutExtension(fileName));
                    File.Delete(fileName);
                }
                else if(Path.GetExtension(fileName)==".gz" && Path.GetFileNameWithoutExtension(fileName).Contains("tar"))
                {
                    Console.WriteLine(fileName);

                    ExtractTGZ(fileName, Path.GetDirectoryName(fileName) + @"\" + Path.GetFileNameWithoutExtension(fileName));
                    File.Delete(fileName);

                }
                else if(Path.GetExtension(fileName)==".tar")
                {
                    Console.WriteLine(fileName);
                    ExtractTar(fileName, Path.GetDirectoryName(fileName) + @"\" + Path.GetFileNameWithoutExtension(fileName));
                    File.Delete(fileName);
                }
                else if (Path.GetExtension(fileName) == ".gz" && !(Path.GetFileNameWithoutExtension(fileName).Contains("tar")))
                {
                    Console.WriteLine(fileName);
                    ExtractGZip(fileName, Path.GetDirectoryName(fileName) + @"\" + Path.GetFileNameWithoutExtension(fileName));
                    File.Delete(fileName);
                }

                //Console.WriteLine(fileName);

            }

            foreach (string directory in Directory.GetDirectories(path))
            {
                FindFiles(directory);
            }

        }

        public static void ExtractZipFile(string archiveFilenameIn, string password, string outFolder)
        {
            ZipFile zf = null;
            try
            {
                FileStream fs = File.OpenRead(archiveFilenameIn);
                zf = new ZipFile(fs);
                if (!String.IsNullOrEmpty(password))
                {
                    zf.Password = password;     // AES encrypted entries are handled automatically
                }
                foreach (ZipEntry zipEntry in zf)
                {
                    if (!zipEntry.IsFile)
                    {
                        continue;           // Ignore directories
                    }
                    String entryFileName = zipEntry.Name;

                    byte[] buffer = new byte[4096];     // 4K is optimum
                    Stream zipStream = zf.GetInputStream(zipEntry);


                    String fullZipToPath = Path.Combine(outFolder, entryFileName);
                    string directoryName = Path.GetDirectoryName(fullZipToPath);
                    if (directoryName.Length > 0)
                        Directory.CreateDirectory(directoryName);

                    using (FileStream streamWriter = File.Create(fullZipToPath))
                    {
                        StreamUtils.Copy(zipStream, streamWriter, buffer);
                    }


                }
            }
            finally
            {
                if (zf != null)
                {
                    zf.IsStreamOwner = true; // Makes close also shut the underlying stream
                    zf.Close(); // Ensure we release resources
                }
            }
        }

        public static void ExtractTGZ(String gzArchiveName, String destFolder)
        {

            Stream inStream = File.OpenRead(gzArchiveName);
            Stream gzipStream = new GZipInputStream(inStream);

            TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
            tarArchive.ExtractContents(destFolder);
            tarArchive.Close();

            gzipStream.Close();
            inStream.Close();
        }

        public static void ExtractTar(String tarFileName, String destFolder)
        {

            Stream inStream = File.OpenRead(tarFileName);

            TarArchive tarArchive = TarArchive.CreateInputTarArchive(inStream);
            tarArchive.ExtractContents(destFolder);
            tarArchive.Close();

            inStream.Close();
        }

        public static void ExtractGZip(string gzipFileName, string targetDir)
        {


            using (FileStream fInStream = new FileStream(gzipFileName, FileMode.Open, FileAccess.Read))
            {
                using (GZipStream zipStream = new GZipStream(fInStream, CompressionMode.Decompress))
                {

                    using (FileStream fOutStream = new FileStream(targetDir, FileMode.Create, FileAccess.ReadWrite))
                    {
                        byte[] tempBytes = new byte[4096];
                        int i;
                        while ((i = zipStream.Read(tempBytes, 0, tempBytes.Length)) != 0)
                        {
                            fOutStream.Write(tempBytes, 0, i);
                        }
                    }
                }
            }
        }