Windows 8開発WinRTによるZIPファイルの解凍およびフォルダのZIP圧縮

8532 ワード

Win 8 Modern UIアプリを開発する際に、ZIP圧縮と解凍ファイル(GZIPではないことに注意)を使う必要がある場合は、まずSharpZipLibを使いたいかもしれません.WP 7のときにこのクラスライブラリを使っていたからです.ただし、WIN 8の使用開始に伴う.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にフォルダを新規作成し、実際のニーズに応じて変更できます)であり、2番目のパラメータは圧縮ファイルのバイト配列であり、この配列はネットワークダウンロードまたは他の独立したストレージ空間のファイルに由来する可能性があります.
フォルダの圧縮(単一のファイルを圧縮する必要がある場合は、次のコードからコードを抽出できます):
        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()メソッドは、1つのフォルダの極小フォルダとファイルをZIPファイルに圧縮し、具体的にはAddZipFolderToEntryを再帰的に呼び出す.