Winrt - 解压缩文件层次结构

时间:2014-06-14 06:15:52

标签: c# windows-runtime windows-store-apps

我正在处理将zip文件解压缩到一些文件层次结构到本地文件夹。我尝试了ZipArchive,但winrt不支持扩展方法 ExtractToDirectory 。其他一些可能性是DotNetZip和SharpZipLib,但winrt也不支持这些库。

Zip层次结构文件可能如下所示(我假设层次结构的深度最大为2):
folder1 / picture1.jpg
folder1 / picture2.jpg
folder2 / picture1.jpg
folder2 / picture2.jpg

一些简化的代码示例:

var data = await client.GetByteArrayAsync("..../file.zip");

var folder = Windows.Storage.ApplicationData.Current.LocalFolder;
var option = Windows.Storage.CreationCollisionOption.ReplaceExisting;

var file = await folder.CreateFileAsync("file.zip", option);
Windows.Storage.FileIO.WriteBytesAsync(file, data);

// zip is saved to Local folder and now I need extract files hierarchy from this zip 

对于这个问题,你有一些聪明而简单的解决方案吗?你知道winrt或Portable类库的一些有用的库,nuget包吗?

1 个答案:

答案 0 :(得分:2)

我必须使用ZipArchive处理这些内容的一些扩展方法。

public static async Task<IStorageItem> CreatePath(this StorageFolder folder, string fileLocation, CreationCollisionOption fileCollisionOption, CreationCollisionOption folderCollisionOption)
{
    var localFilePath = PathHelper.ToLocalPath(fileLocation).Replace(PathHelper.ToLocalPath(folder.Path), "");
    if (localFilePath.Length > 0 && (localFilePath[0] == '/' || localFilePath[0] == '\\'))
    {
        localFilePath = localFilePath.Remove(0, 1);
    }

    if (localFilePath.Length == 0)
    {
        return folder;
    }

    var separatorIndex = localFilePath.IndexOfAny(new char[] { '/', '\\' });
    if (separatorIndex == -1)
    {
        return await folder.CreateFileAsync(localFilePath, fileCollisionOption);
    }
    else
    {
        var folderName = localFilePath.Substring(0, separatorIndex);
        var subFolder = await folder.CreateFolderAsync(folderName, folderCollisionOption);
        return await subFolder.CreatePath(fileLocation.Substring(separatorIndex + 1), fileCollisionOption, folderCollisionOption);
    }
}

public static async Task ExtractToFolderAsync(this ZipArchive archive, StorageFolder folder)
{
    foreach (var entry in archive.Entries)
    {
        var storageItem = await folder.CreatePathAsync(entry.FullName, CreationCollisionOption.OpenIfExists, CreationCollisionOption.OpenIfExists);
        StorageFile file;
        if ((file = storageItem as StorageFile) != null)
        {
            using (var fileStream = await file.OpenStreamForWriteAsync())
            {
                using (var entryStream = entry.Open())
                {
                    await entryStream.CopyToAsync(fileStream);
                }
            }
        }
    }
}