Saturday, June 2, 2012

How to decompress files in Metro style applications?

In this blog post, I am going to demonstrate on how to use ZipArchive class in Metro style app to decompress a set of files and save the extracted files to a particular location.

Steps to decompress a set of files:

Step 1: Select the compressed file to decompress.

//Initialize file open picker
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.ViewMode = PickerViewMode.List;
//Suggest start location
fileOpenPicker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
//Add file type filter
//Opens file open picker to allow the user to select the compressed file
StorageFile stgFile = await fileOpenPicker.PickSingleFileAsync();

Step 2: Select folder to extract the files

//Initialize folder picker
FolderPicker saveFolder = new FolderPicker();
//Suggest start location
saveFolder.SuggestedStartLocation = PickerLocationId.Desktop;
//Add file type filter
//Opens folder picker to allow the user to select the folder to extract the compressed items
StorageFolder storageFolder = await saveFolder.PickSingleFolderAsync();

Step 3: Use ZipArchive class to extract the files to the selected folder
//Read the stream from the compressed file
Stream stream = await stgFile.OpenStreamForReadAsync();
//Copy it to Memory stream for further manipulation
MemoryStream ms = new MemoryStream();
await stream.CopyToAsync(ms);
ms.Position = 0;

//Open Zip archive of the compressed file
zipArchive = new ZipArchive(ms, ZipArchiveMode.Read);

//For each archive entry, create file and folder accordingly and then copy the entry stream to the file.
foreach (ZipArchiveEntry entry in zipArchive.Entries)
StorageFile storageFile;
//Assign Selected save folder
StorageFolder stgFolder = storageFolder;
//Create Folder
stgFolder = await CreateFolder(storageFolder, entry.FullName.Replace(entry.Name, string.Empty));
//Create File
storageFile = await stgFolder.CreateFileAsync(entry.Name, CreationCollisionOption.ReplaceExisting);
//Open file stream for writing
Stream s = await storageFile.OpenStreamForWriteAsync();
//Copy the entry stream to the file stream
await entry.Open().CopyToAsync(s);

Helper methods:
Create folder based on the file path present in Zip Archive entry

async Task<StorageFolder> CreateFolder(StorageFolder stgFolder, string path)
//Split the folder path for creating sub folder
string[] locationSplit = path.Split(new char[] { '/' });
for (int i = 0; i < locationSplit.Length; i++)
//Create folder
if (locationSplit[i] != string.Empty)
stgFolder = await stgFolder.CreateFolderAsync(locationSplit[i], CreationCollisionOption.OpenIfExists);
return stgFolder;

Thus the files under the selected compressed file are extracted to a particular location.


No comments:

Post a Comment