【问题标题】:decompress a ZIP file on windows 8 C#在 Windows 8 C# 上解压缩 ZIP 文件
【发布时间】:2013-04-05 22:29:15
【问题描述】:

我正在为 Windows 8 构建一个 Metro 风格的应用程序,我有一个从 Web 服务下载的 zip 文件,我想将其解压缩。

我已经看到了压缩和解压缩的示例,但这需要一个文件来压缩/解压缩它。我需要提取一个完整的目录结构。

这是我目前所拥有的:

var appData = ApplicationData.Current;
var file = await appData.LocalFolder.GetItemAsync("thezip.zip") as StorageFile;
var decompressedFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("tempFileName", CreationCollisionOption.GenerateUniqueName);
using (var decompressor = new Decompressor(await file.OpenSequentialReadAsync()))
using (var decompressedOutput = await decompressedFile.OpenAsync(FileAccessMode.ReadWrite))
{
    var bytesDecompressed = await RandomAccessStream.CopyAsync(decompressor, decompressedOutput);
}

但这并不好,bytesDecompressed 变量的大小始终为零,但 zip 文件为 1.2MB

我们将不胜感激。

编辑:回答,感谢Mahantesh

下面是解压文件的代码:

private async void UnZipFile()
{
    var folder = ApplicationData.Current.LocalFolder;

    using (var zipStream = await folder.OpenStreamForReadAsync("thezip.zip"))
    {
        using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
        {
            await zipStream.CopyToAsync(zipMemoryStream);

            using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
            {
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    if (entry.Name != "")
                    {
                        using (Stream fileData = entry.Open())
                        {
                            StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
                            using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
                            {
                                await fileData.CopyToAsync(outputFileStream);
                                await outputFileStream.FlushAsync();
                            }
                        }
                    }
                }
            }
        }
    }
}

【问题讨论】:

  • 我已经实现了这个代码来解压我的 ApplicationData.Current.LocalFolder 文件夹中的一个 zip 文件。但 zip 包含文件夹和子文件夹。因此,代码在运行时会在这些子文件夹中执行 await outputFile.OpenStreamForWriteAsync() 操作时给出“访问被拒绝错误”。但是,当代码多次运行时,在任何随机子文件夹中都会出现错误。有什么想法吗??
  • 好的..错误是我将 UnZipFile 方法作为我不应该做的静态方法...

标签: c# compression windows-8


【解决方案1】:

在 Metro 风格的应用程序中,您可以使用 ZipArchive、ZipArchiveEntry、DeflateStream 和 GZipStream 类中的方法处理压缩文件。

参考:UnZip File in Metro

参考:Folder zip/unzip in metro c#

【讨论】:

    【解决方案2】:

    根据您的代码和建议,我想出了一个支持文件夹提取的,这是我的需求之一:

    private async void UnZipFile(string file)
    {
        var folder = ApplicationData.Current.LocalFolder;
    
        using (var zipStream = await folder.OpenStreamForReadAsync(file))
        {
            using (MemoryStream zipMemoryStream = new MemoryStream((int)zipStream.Length))
            {
                await zipStream.CopyToAsync(zipMemoryStream);
    
                using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Read))
                {
                    foreach (ZipArchiveEntry entry in archive.Entries)
                    {
    
                        if (entry.Name == "")
                        {
                            // Folder
                            await CreateRecursiveFolder(folder, entry);
                        }
                        else
                        {
                            // File
                            await ExtractFile(folder, entry);
                        }
                    }
                }
            }
        }
    }
    
    private async Task CreateRecursiveFolder(StorageFolder folder, ZipArchiveEntry entry)
    {
        var steps = entry.FullName.Split('/').ToList();
    
        steps.RemoveAt(steps.Count() - 1);
    
        foreach (var i in steps)
        {
            await folder.CreateFolderAsync(i, CreationCollisionOption.OpenIfExists);
    
            folder = await folder.GetFolderAsync(i);
        }
    }
    
    private async Task ExtractFile(StorageFolder folder, ZipArchiveEntry entry)
    {
        var steps = entry.FullName.Split('/').ToList();
    
        steps.RemoveAt(steps.Count() - 1);
    
        foreach (var i in steps)
        {
            folder = await folder.GetFolderAsync(i);
        }
    
        using (Stream fileData = entry.Open())
        {
            StorageFile outputFile = await folder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
    
            using (Stream outputFileStream = await outputFile.OpenStreamForWriteAsync())
            {
                await fileData.CopyToAsync(outputFileStream);
                await outputFileStream.FlushAsync();
            }
        }
    }
    

    【讨论】:

    • 这很好,但是当整个过程完成时您如何收到通知?
    • 意识到我对CreateRecursiveFolderExtractFile 方法都使用了await,所以它不会是真正的异步,UnZipFile 方法只会返回当一切准备就绪时。您必须在调用UnZipFile 时使用await 子句。
    • @Tuco 我已经实现了此代码来解压缩我的 ApplicationData.Current.LocalFolder 文件夹中的 zip 文件。但 zip 包含文件夹和子文件夹。因此,在解压缩这些子文件夹中的数据时,代码会给出“拒绝访问错误”。但是,当代码多次运行时,在任何随机子文件夹中都会出现错误。有什么想法吗??
    • @Tuco Ok..错误是我将解压缩方法作为我不应该做的静态方法...
    猜你喜欢
    • 1970-01-01
    • 2012-03-22
    • 1970-01-01
    • 2012-01-08
    • 2011-11-30
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    相关资源
    最近更新 更多