Pull to refresh

Доступ к файловой системе из Portable Class Library (PCL)

Reading time 3 min
Views 5.6K
В один прекрасный день у меня появилась идея о портировании своего .NET кода на другие платформы с вынесением основной логики (все что не касается UI) в отдельную библиотеку Portable Class Library (PCL).

В теории звучит все классно – с PCL можно работать практически на всех устройствах, и не только с .NET Framework, но и даже с Mono! С таком подходом открываются большие мультиплатформенные перспективы, к примеру, перенос кода Windows Phone на Android и iOS с помощью Xamarin.





Но ознакомившись с PCL поближе, я пришел к выводу, что такая библиотека это по сути урезанный .NET, учитывающий ограничения каждой платформы. То есть даже на с виду похожих WP8 и W8 не удастся все спихнуть в PCL.



Таблица возможностей PCL на разных платформах


На первый взгляд мой код должен был перейти без проблем (целевые платформы: Windows .NET, Windows 8, Windows Phone), но компилятор обругал System.IO, а именно StreamReader, который напрямую открывал файл.

Вспомнив что у Windows 8 и Windows Phone совершенно другие способы для работы с файлами и разные между собой:

WP использует IsolatedStorage для доступа к файлам приложения, а Windows 8, хоть и имеет доступ к публичным папкам, но делает это через Windows.Storage (WP8 тоже теперь может через него, но для сохранения поддержки WP7 такой способ не рекомендуется использовать). Попользовавшись гуглом, мне стало ясно, что организовать доступ к файлам на чистом PCL невозможно, а советы вроде передачи Steam уже из приложения или жесткого включения файла в DLL для моего решения не подходили. Дело в том, что программа работала с большим внешним словарем и сохраняла временные результаты работы в файлах. Но тут на глаза попалась библиотека PCLStorage, обещавшая какую-никакую работу с ФС через PCL.

PCLStorage предоставляет три интерфейса – IFIle, IDirectory, IFileSystem, все они обеспечивают асинхронные операции чтения и записи файлов и директорий.

Примечание: Все дальнейшие тесты проводились на «классическом» Windows.

Пример записи файла:

 public async Task PCLCreateFile(string name, string content)
        {
            IFolder localStorage = FileSystem.Current.LocalStorage;
      
            IFolder contentFolder = await localStorage.CreateFolderAsync("Content", CreationCollisionOption.OpenIfExists);

            IFile file = await contentFolder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);

            await file.WriteAllTextAsync(content);
        }


Пример чтения файла:

      public async Task<string> PCLReadFile(string name)
        {
            IFolder localStorage = FileSystem.Current.LocalStorage;

            IFolder contentFolder = await localStorage.GetFolderAsync("Content");

            IFile file = await contentFolder.GetFileAsync(name);

            return await file.ReadAllTextAsync();
        }


Выглядит и работает все отлично. Но… как получить доступ к файлу, который находится в директории программы?

IFileSystem возвращает два пути LocalStorage и RoamingStorage. Первый указывает на директорию которая выделена для программы в текущей системе, второй на публичную директорию для синхронизации данных. В частности в Windows LocalStorage указывал на (AppData\Local), что далеко не являлось директорией приложения и не содержало никаких файлов.

На директорию приложения PCLStorage, к сожалению, указать не могло.

Конечно, возможно было создать специальный инсталлятор, но как быть в случае Store приложений? Тем не менее, решение появилось – копирование файлов в LocalStorage из самого приложения (или загрузка из сети в самом PCL (не проверялось)). Что же, способ в итоге вышел более простой, чем передача Stream, плюс появилась возможность работать со временными файлами в ограниченной среде портативной библиотеки.

P.S.: Под конец эксперимента оказалось что поддержку WP7 из последней версии выкинули, из-за чего собственно говоря все и затевалось (Из-за раздельного использования IsolatedStorage на WP и Windows.Storage на Windows 8).
Tags:
Hubs:
+5
Comments 5
Comments Comments 5

Articles