将文件夹压缩到PCL的gzip / zip文件

时间:2016-05-16 14:19:11

标签: c# zip win-universal-app gzip portable-class-library

我正在使用相同的解决方案开发UWP和Windows Phone 8.1。

在这两个项目中,我需要一个将整个文件夹压缩到一个gzip文件的功能(以便将其发送到服务器)。

图书馆我尝试过并遇到过以下问题:

SharpZipLib - 使用System.IClonable,我无法在我的PCL项目中使用它

DotNetZip - 不支持PCL / UWP

System.IO.Compression - 仅使用Stream,无法压缩整个文件夹

我可以拆分每个平台的实现(尽管它并不完美),但我仍然没有找到可以在UWP中使用的东西。

任何帮助都会受到欢迎

2 个答案:

答案 0 :(得分:0)

好的,所以我发现这个名为SharpZipLib.Portable的项目也是一个开源软件 Github:https://github.com/ygrenier/SharpZipLib.Portable

真的很好:))

答案 1 :(得分:-1)

在UWP库上工作时,您必须使用System.IO.Compression的Stream子系统。当您需要PCL版本的.NET Framework时,有许多此类限制。与之共存。

在你的背景下并没有太大的麻烦。

所需的用途是:

using System;
using System.IO;
using System.IO.Compression;

然后方法......

    private void CreateArchive(string iArchiveRoot)
    {
        using (MemoryStream outputStream = new MemoryStream())
        {
            using (ZipArchive archive = new ZipArchive(outputStream, ZipArchiveMode.Create, true))
            {
                //Pick all the files you need in the archive.
                string[] files = Directory.GetFiles(iArchiveRoot, "*", SearchOption.AllDirectories);

                foreach (string filePath in files)
                {
                    FileAppend(iArchiveRoot, filePath, archive);
                }
            }
        }
    }

    private void FileAppend(
        string iArchiveRootPath,
        string iFileAbsolutePath,
        ZipArchive iArchive)
    {
        //Has to return something like "dir1/dir2/part1.txt".
        string fileRelativePath = MakeRelativePath(iFileAbsolutePath, iArchiveRootPath);

        ZipArchiveEntry clsEntry = iArchive.CreateEntry(fileRelativePath, CompressionLevel.Optimal);
        Stream entryData = clsEntry.Open();

        //Write the file data to the ZipArchiveEntry.
        entryData.Write(...);
    }

    //http://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path
    private string MakeRelativePath(
        string fromPath, 
        string toPath)
    {
        if (String.IsNullOrEmpty(fromPath)) throw new ArgumentNullException("fromPath");
        if (String.IsNullOrEmpty(toPath))   throw new ArgumentNullException("toPath");

        Uri fromUri = new Uri(fromPath);
        Uri toUri = new Uri(toPath);

        if (fromUri.Scheme != toUri.Scheme) { return toPath; } // path can't be made relative.

        Uri relativeUri = fromUri.MakeRelativeUri(toUri);
        String relativePath = Uri.UnescapeDataString(relativeUri.ToString());

        if (toUri.Scheme.Equals("file", StringComparison.OrdinalIgnoreCase))
        {
            relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
        }

        return relativePath;
    }