Windows Phone 7.5 での圧縮の使用

原文の記事の投稿日: 2012 年 4 月 14 日 (土曜日)

注意: いつもどおり、私が実際に入力した内容に対してこのサイトで行われる乱暴な書式設定に対抗するため、この投稿の Word 版を添付してあります。:-)

Windows Phone で開発したことがあればわかると思いますが、圧縮と圧縮解除のサポートは組み込まれていません。多くの人が CodePlex での SharpCompress プロジェクトを挙げていますが、私も結局これを使用しています。ただし、この方法の重要な不備として、電話機でのファイルの圧縮解除に関するドキュメントが用意されていません。私は、Windows で圧縮されたファイルを WriteAllToDirectory メソッドを使用して圧縮解除する Winform アプリケーション用のコードを相当量自分で作成しました。ただし、このメソッドは Windows Phone 用のアセンブリには含まれていません。さらに、SharpCompress 用の Windows Phone アセンブリを使用するときに解凍先となるパスを指定することはできず、ストリーム オブジェクトを提供する必要があります。

最終的には動作しましたが、Windows の製品版でこれを使用するときとは大きく異なる処理を行う必要があります。ここでは、これについてのヒントをいくつか示します。

1. Reader ファクトリから取得する 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」をご覧ください。