在 Windows Phone 7.5 上使用壓縮
英文原文已於 2012 年 4 月 14 日星期六發佈
注意:按照慣例,本文另附有 Word 版本以供對照,因為這個網站的版面格式總是亂七八糟,我原本打好的樣子到了這邊就變得面目全非,可惡~~~!
我相信此處的看官們有很多人都認識 Windows Phone 的開發人員,知道該系統本身並未提供內建的壓縮和解壓縮功能。許多玩家們建議改用 CodePlex 的 SharpCompress 方案,而我最後選擇的方法也是如此。這套做法最大的缺憾,就是完全沒有任何文件說明可以教您到底該怎麼在手機上解壓縮檔案。我手上有滿多針對 WinForm 應用程式所撰寫的現成程式碼,採用了 WriteAllToDirectory 方法在 Windows 上解壓縮 Zip 檔。但是這方法並不存在於 Windows Phone 的組件當中。此外,當您使用 Windows Phone 的 SharpCompress 組件時,您也不能直接輸入您要解壓縮的目標路徑,您必須提供給它一個資料流物件。
這方式最終是可行的,但操作的方法會和在完整版的 Windows 上很不一樣。以下是幾個要訣供您參考:
1. 一一列舉所有您從 ReaderFactory 取得的 IReader 之 Entry 集合:
//"sr" is a stream reader object from previous code that contains the byte array of the actual zip file
using (var reader = ReaderFactory.Open(sr))
{
while (reader.MoveToNextEntry())
{
//IsDirectory always returns false in everything I've seen so far
if (!reader.Entry.IsDirectory)
{
//process the entry, described next
}
else
{
//do not know of a scenario where we can end up here
Debug.WriteLine(reader.Entry.FilePath);
}
}
}
2. 建立檔案目錄,然後準備一個您可用以寫入的 IsolatedStorageFileStream 執行個體:
//IsDirectory always returns false in everything I've seen so far
if (!reader.Entry.IsDirectory)
{
IsolatedStorageFileStream theFile = GetLocalFile(reader.Entry.FilePath);
}
private IsolatedStorageFileStream GetLocalFile(string fullPath)
{
IsolatedStorageFileStream fs = null;
try
{
//get isolated storage so we can create directories and decompress
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();
//trim everything from the last index of /, which is the file
//name, i.e. it will look like folder/folder/folder/filename.txt
string dirPath = fullPath.Substring(0, fullPath.LastIndexOf("/"));
//what's nice is you can create the full folder path in one call
if (!storage.DirectoryExists(dirPath))
storage.CreateDirectory(dirPath);
//now that all the directories exist, create a stream for the
// file – again, cool because you can just give the full path
fs = storage.CreateFile(fullPath);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return fs;
}
3. 現在您已經有一項資料流,便可以用 WriteEntryTo 方法寫出個別檔案了:
if (!reader.Entry.IsDirectory)
{
IsolatedStorageFileStream theFile = GetLocalFile(reader.Entry.FilePath);
if (theFile != null)
reader.WriteEntryTo(theFile);
}
希望這篇文章對您有所幫助,沒有文件說明實在很令人苦惱,我只能邊做邊摸索。
這是翻譯後的部落格文章。英文原文請參閱 Using Compression on Windows Phone 7.5