简体   繁体   English

通用 Windows 平台 ZipFile.CreateFromDirectory 创建空 ZIP 文件

[英]Universal Windows Platform ZipFile.CreateFromDirectory creates empty ZIP file

I have a problem with zipping existing directories.我在压缩现有目录时遇到问题。 When I try to compress an existing directory, I always get an empty zip file.当我尝试压缩现有目录时,我总是得到一个空的 zip 文件。 My code is based on this example from MSDN .我的代码基于MSDN 中的这个示例。 There are no exceptions when debugging the application.调试应用程序时没有例外。

My code:我的代码:

private async void PickFolderToCompressButton_Click(object sender, RoutedEventArgs e)
{
    // Clear previous returned folder name, if it exists, between iterations of this scenario
    OutputTextBlock.Text = "";

    FolderPicker folderPicker = new FolderPicker();
    folderPicker.SuggestedStartLocation = PickerLocationId.Desktop;
    folderPicker.FileTypeFilter.Add(".dll");
    folderPicker.FileTypeFilter.Add(".json");
    folderPicker.FileTypeFilter.Add(".xml");
    folderPicker.FileTypeFilter.Add(".pdb");
    StorageFolder folder = await folderPicker.PickSingleFolderAsync();
    if (folder != null)
    {
        // Application now has read/write access to all contents in the picked folder (including other sub-folder contents)
        StorageApplicationPermissions.FutureAccessList.AddOrReplace("PickedFolderToken", folder);
        OutputTextBlock.Text = $"Picked folder: {folder.Name}";

        var files  = await folder.GetFilesAsync();
        foreach (var file in files)
        {
            OutputTextBlock.Text += $"\n {file.Name}";
        }

        await Task.Run(() =>
        {
            try
            {
                ZipFile.CreateFromDirectory(folder.Path, $"{folder.Path}\\{Guid.NewGuid()}.zip",
                    CompressionLevel.NoCompression, true);
                Debug.WriteLine("folder zipped");
            }
            catch (Exception w)
            {
                Debug.WriteLine(w);
            }
        });
    }
    else
    {
        OutputTextBlock.Text = "Operation cancelled.";
    }
}

A Zip file is created, but it is always empty.创建了一个 Zip 文件,但它始终为空。 There are many files in the source folder.源文件夹中有很多文件。

We found this could be caused by the implementation of the .NET Core for the filesystem api.我们发现这可能是由文件系统 api 的 .NET Core 实现引起的。

Current workaround is to firstly put your folder to be zipped to the local data folder of the windows runtime app, and read from this folder could generate an expected result when using the zipfile class.当前的解决方法是首先将要压缩的文件夹放在 windows 运行时应用程序的本地数据文件夹中,在使用 zipfile 类时从该文件夹中读取可能会产生预期的结果。

You can refer to a related post on MSDN.您可以参考 MSDN 上的相关帖子

The zipfile library only supports zipping back to application localfolder. zipfile 库仅支持压缩回应用程序本地文件夹。 If you have the permission token from other folder, you might want to zip directly.如果您有来自其他文件夹的权限令牌,您可能想直接压缩。 The writeZip function can also be used to add a separate file from elsewhere. writeZip 函数还可用于从别处添加单独的文件。

        public async void Backup(StorageFolder source, StorageFolder destination)
        {
            var zipFile = await destination.CreateFileAsync("backup.zip",
               CreationCollisionOption.ReplaceExisting);

            var zipToCreate = await zipFile.OpenStreamForWriteAsync();
            using (var archive = new ZipArchive(zipToCreate, ZipArchiveMode.Update))
            {
                var parent = source.Path.Replace(source.Name, "");
                await RecursiveZip(source, archive, parent);
            }
        }

        private async Task RecursiveZip(StorageFolder sourceFolder, ZipArchive archive, string sourceFolderPath)
        {
            var files = await sourceFolder.GetFilesAsync();
            foreach (var file in files)
            {
                await WriteZip(file, archive, sourceFolderPath);
            }

            var subFolders = await sourceFolder.GetFoldersAsync();
            foreach (var subfolder in subFolders)
            {
                await RecursiveZip(subfolder, archive, sourceFolderPath);
            }
        }

        private async Task WriteZip(StorageFile file, ZipArchive archive, string sourceFolderPath)
        {
            var entryName = file.Path.Replace(sourceFolderPath, "");
            var readmeEntry = archive.CreateEntry(entryName, CompressionLevel.Optimal);
            var reader = await file.OpenStreamForReadAsync();
            using (var entryStream = readmeEntry.Open())
            {
                await reader.CopyToAsync(entryStream);
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM