在開發一個Win8 Modern UI APP時,如果需要用到ZIP壓縮和解壓文件(注意不是GZIP),可能會首先想到使用SharpZipLib,由於我們在WP7的時候就使用的這個類庫。不過,隨着WIN8開始使用.Net 4.5和C# 5.0,引入了一個新功能,其實ZIP壓縮與解壓縮已經可以不用第三方類庫就能實現了。
主要需要用到System.IO.Compression命名空間。下面演示程序需要用到的全部命名空間如下:
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; using Windows.Storage; using Windows.Storage.Streams;
對zip文件的解壓縮操作:
public async Task<StorageFolder> UnZipFile(string folderName, byte[] data) { StorageFolder unZipfolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(folderName, CreationCollisionOption.OpenIfExists); var stream = new MemoryStream(data); var zipArchive = new ZipArchive(stream, ZipArchiveMode.Read); foreach (var zipArchiveEntry in zipArchive.Entries) { if (!String.IsNullOrEmpty(zipArchiveEntry.FullName)) { if (!zipArchiveEntry.FullName.EndsWith("/")) { string fileName = zipArchiveEntry.FullName.Replace("/", "\\"); using (Stream fileData = zipArchiveEntry.Open()) { StorageFile newFile = await unZipfolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream newFileStream = await newFile.OpenAsync(FileAccessMode.ReadWrite)) { using (Stream s = newFileStream.AsStreamForWrite()) { await fileData.CopyToAsync(s); await s.FlushAsync(); s.Dispose(); } newFileStream.Dispose(); } } } } } return unZipfolder; }
UnZipFile()方法,傳入的第一個參數為欲解壓的文件位置(解壓縮位置LocalFolder中新建一個文件夾,可以根據實際需求進行修改),第二個參數為壓縮文件的字節數組,這個數組可能來源於網絡下載或者其他獨立存儲空間中的文件。
對文件夾的壓縮(如果需要壓縮單個文件,代碼可從下面的代碼中提取):
public async Task<byte[]> ZipFolder(StorageFolder folder) { using (var zipMemoryStream = new MemoryStream()) { using (var zipArchive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create)) { await AddZipFolderToEntry(zipArchive, folder, ""); } return zipMemoryStream.ToArray(); } } private async Task<bool> AddZipFolderToEntry(ZipArchive zipArchive, StorageFolder folder, string entryFirst) { IReadOnlyList<StorageFile> filesToCompress = await folder.GetFilesAsync(); foreach (StorageFile fileToCompress in filesToCompress) { byte[] buffer = (await FileIO.ReadBufferAsync(fileToCompress)).ToArray(); ZipArchiveEntry entry = zipArchive.CreateEntry(entryFirst + fileToCompress.Name); using (Stream entryStream = entry.Open()) { await entryStream.WriteAsync(buffer, 0, buffer.Length); } } var childrenFolder = await folder.GetFoldersAsync(); foreach (var storageFolder in childrenFolder) { await AddZipFolderToEntry(zipArchive, storageFolder, entryFirst + storageFolder.Name + "/"); } return true; }
ZipFolder()方法為將一個文件夾極其子文件夾與文件壓縮成一個ZIP文件,具體過程為遞歸調用AddZipFolderToEntry。
錦燕雲 微博 http://www.weibo.com/jinyanyun http://www.cnblogs.com/vistach/archive/2012/11/05/Windows8_Win8_WinRT_MetroStyleApps_ModernUIApps_Zip_UnZip_Compress_Decompression.html