Использование сжатия в 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