Ответ 1
В приложениях в стиле Metro вы работаете со сжатыми файлами, используя методы в классах ZipArchive, ZipArchiveEntry, DeflateStream и GZipStream.
Обратитесь: Отменить файл в Metro
Обратитесь: Папка zip/unzip в metro С#
Я создаю приложение стиля метро для Windows 8, и у меня есть 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
Любая помощь здесь будет принята с благодарностью.
EDIT: ответьте, спасибо 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();
}
}
}
}
}
}
}
}
В приложениях в стиле Metro вы работаете со сжатыми файлами, используя методы в классах ZipArchive, ZipArchiveEntry, DeflateStream и GZipStream.
Обратитесь: Отменить файл в Metro
Обратитесь: Папка zip/unzip в metro С#
Основываясь на вашем коде и предложениях, я придумал тот, который поддерживает извлечение папок, что было одной из моих потребностей:
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();
}
}
}