Использование сжатия в Windows Phone 7.5

Исходная статья опубликована в субботу 14 апреля 2012 г.

Примечание. Как обычно я прилагаю Word-версию данной статьи, потому что этот сайт жестоко искажает форматирование вводимого текста.

Я уверен, что многие из вас, кто занимался разработкой для Windows Phone, знают, что в этой системе нет встроенной поддержки сжатия и распаковки. Многие советовали приглядеться к проекту SharpCompress в CodePlex, и в конце концов я стал использовать именно его. Однако очень важным его недостатком является полное отсутствие документации по распаковке файлов на телефоне. Мне пришлось написать изрядную порцию кода для приложения winform, в котором для распаковки сжатого файла использовался метод WriteAllToDirectory в Windows. Однако этот метод отсутствует в сборке для Windows Phone. Кроме того, при использовании сборки Windows Phone нельзя просто указать SharpCompress путь для распаковки, вместо этого нужно указать объект потока.

В конечном счете этот метод работает, но требует немного другого подхода по сравнению с использованием полной версии Windows. Вот некоторые советы, которые помогут добиться нужного результата:

1. Создайте перечисление с помощью коллекции Entry интерфейса IReader, который берется из фабрики Reader:

//"sr" — это потоковый объект чтения из предыдущего кода, в котором содержится байтовый массив фактического архивного файла

using (var reader = ReaderFactory.Open(sr))

{

while (reader.MoveToNextEntry())

{

   //IsDirectory всегда возвращает значение false

   if (!reader.Entry.IsDirectory)

   {

      //обработка записи, описывается далее

   }

   else

   {

       //не знаю сценария, который приведет в это место

       Debug.WriteLine(reader.Entry.FilePath);

   }

}

}

2. Создайте каталог (каталоги) для файлов, а затем получите экземпляр IsolatedStorageFileStream, в который можно проводить запись:

//IsDirectory всегда возвращает значение false

if (!reader.Entry.IsDirectory)

{

       IsolatedStorageFileStream theFile = GetLocalFile(reader.Entry.FilePath);

}

 

private IsolatedStorageFileStream GetLocalFile(string fullPath)

{

   IsolatedStorageFileStream fs = null;

 

   try

   {

       //получение изолированного хранилища для создания каталогов и распаковки

       IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication();

 

       //отсечение всех данных после последней позиции индекса в /, что является

       //именем файла, то есть будет иметь вид папка/папка/папка/имя_файла.txt

       string dirPath = fullPath.Substring(0, fullPath.LastIndexOf("/"));

 

       //удобно, что можно создать полный путь к папке в одном вызове

       if (!storage.DirectoryExists(dirPath))

          storage.CreateDirectory(dirPath);

 

       //теперь после создания всех каталогов создадим поток для

       // файла – это также удобно, поскольку можно просто указать полный путь

       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