Работа с файлами
Цель изучения
Материалы к модулю Вы можете скачать здесь.
В этом модуле вы изучите ограничения доступа в приложениях для Магазина Windows, способы настройки манифеста приложения для разрешения доступа к файлам, и средствам выбора файлов (File Pickers) для доступа к пользовательским файлам. Также вы узнаете о том, как можно использовать класс StorageFolder для сохранения специфических данных приложения.
Начало работы
Вам понадобится решение Starter из подпапки \Module_6_Assets\Starter. Это итоговый проект из предыдущего модуля.
Доступ к файлам в WinRT-приложениях
В отличие от традиционных приложений Windows, WinRT-приложения по умолчанию ограничивают доступ к пользовательским данным и устройствам. Если WinRT-приложение требует разрешения только на чтение одного или нескольких файлов, то, скорее всего, можно использовать средство выбора файлов (File Picker) с настройками безопасности, установленными по умолчанию.
При помощи элемента управления File Picker можно:
- разрешить пользователю просматривать и выбирать один или несколько файлов с устройства;
- разрешать пользователю выбирать место сохранения файла.
Также можно использовать File Picker расширенно: для доступа приложений к файлам или доступа приложения к другому приложению.
Однако некоторые разрешения на доступ к файлу не включены по умолчанию из-за настроек безопасности. Если приложению требуется программный доступ к целой пользовательской библиотеке (музыка, видео или другие файлы), необходимо объявлять соответствующую возможность (характеристику) в манифесте приложения.
Например, приложение предназначено для проигрывания всей музыки из библиотеки пользователя. Так как данное приложение запрашивает все музыкальные файлы из пользовательской библиотеки программно, необходимо специально объявлять возможность musicLibrary.
Сценарий | Необходимость объявления возможности |
---|---|
Открытие файла | Нет |
Выбор места сохранения файла | Нет |
Получение списка музыкальных файлов из пользовательской библиотеки | Да. Необходимо объявление в манифесте приложения возможности musicLibary |
Получение списка изображений из пользовательской библиотеки | Да. Необходимо объявление в манифесте приложения |
Когда приложение представлено к сертификации в Магазина Windows, оно исследуется тщательнее, чем больше в нём используется возможностей, поэтому нужно внимательно следить за тем, все ли объявленнные возможности необходимы.
Упражнение: исследование файла манифеста
Для того, чтобы объявить возможности в приложении, необходимо редактировать манифест приложения, который является XML-файлом. В Visual Studio есть специальный редактор для редактирования этого файла.
- Откройте решение Starter из \Module_6_Assets\Starter.
- Найдите файл package.appmanifest в проекте.
- Дважды кликните файл для открытия редактора.
- Перейдите на вкладку Возможности (Capabilities Tab). Здесь есть список всех возможностей, которые можно объявить в приложении. Для просмотра описания этих возможностей посетите страницу: http://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx
- Теперь перейдите на закладку Объявления (Declarations). Эта закладка показывает список доступных контрактов. Контракты описывают, каким образом приложение может взаимодействовать с другими приложениями и с платформой Windows для таких функций, как поиск и совместное использование данных. Контракты будут более подробно рассмотрены в 8 модуле.
Promise-объект для асинхронных операций
Доступ к файлам в WinRT осуществляется асинхронно. Это означает, что процесс доступа к файлу начинается отдельным потоком, а когда файловая операция завершена, происходит возвращение к вызывающему потоку. Фактически, эти операции происходят параллельно с другими (ввод данных, анимация и пр.).
В WinJS есть promise-объект, необходимый для помощи в асинхронных операциях. Promise-объект может быть использован для всех асинхронных операций, включая web-запросы, файловые операции и др., поэтому важно хорошо понимать принцип его действия.
Базовая структура вызова с использованием Promise-объекта выглядит следующим образом (псевдокод):
myObject.doSomethingAsync() .then(onCompleteFunction1, onErrorFunction1, onProgressUpdate1)
myObject
определённый объект, например, объект запроса файла или ссылки.
doSomethingAsync
использование асинхронного метода, например, запрос на открытие файла или загрузка WEB-страницы
then
определяет, что произойдёт, когда асинхронная функция завершится или произойдет ошибка
onCompleteFunction1
функция, которая будет выполняться после завершения асинхронной операции
onErrorFunction1
(опционально) функция, которая будет выполняться, если во время выполнения асинхронной операции возникнет ошибка или исключение
onProgressUpdate1
(опционально) функция, которая будет выполняться, если promise-объект производит обновление элемента управления, позволяющего судить о ходе длительной операции. Обновления прогресса операции не обязательны, но они удобны в продолжительных операциях, где можно показать пользователю визуально, что процесс идёт (как progress bar – строка состояния)
Можно многократно объединять функции then(). Это бывает полезно, когда необходимо использовать несколько асинхронных операций, к примеру, получение данных от веб-сервиса и их последующее сохранение в файл.
Объединение нескольких методов then() может выглядеть так (псевдокод):
myObject.doSomethingAsync() .then(onCompleteFunction1, onErrorFunction1, onProgressUpdate1) .then(onCompleteFunction2, onErrorFunction2, onProgressUpdate2)
Другая важная функция promise – это метод done(). Метод done() похож на метод then() за исключением того, что он может инициировать ошибки, которые могут произойти. Полезно помещать эту функцию последней в цепочке функций, так как этот метод может перехватывать любые ошибки метода then() и инициировать или обрабатывать их.
Использование метода done() совместно с методом then() может выглядеть так:
myObject.doSomethingAsync() .then(onCompleteFunction1, onErrorFunction1, onProgressUpdate1) .done(onCompleteFunction2, onErrorFunction2, onProgressUpdate2)
Упражнение: использование File Picker (средства выбора файла)
Теперь вы имеете представление о том, как функционируют возможности (Capabilities) и средства асинхронного исполнения задач (Promises). Сейчас рассмотрим средство выбора файла (File Picker) для выбора изображения из библиотеки пользователя.
- Нажмите правой кнопкой мыши на подпапку /js/ и выбрать Добавить > Создать элемент (Add > New Item)
- "Выберите Файл JavaScript (JavaScript File" и введите imageUtils.js.
- Добавьте код, показанный ниже. Буден создано пространство имён под именем "ImageUtils". В этом пространстве имён появится функция под названием pickAPicture(), которая использует управление средством выбора файла, чтобы разрешить пользователю выбрать файл. Она также представляет переменную под названием picturePicked, так что выбранный файл будет позже доступен в коде.
Этот код находится в файле \Module_6_Assets\snippets\filePicker.txt
(function () { "use strict"; function pickAPicture() { var openPicker = new Windows.Storage.Pickers.FileOpenPicker(); openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail; openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary; openPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]); openPicker.pickSingleFileAsync().then(function (file) { if (file) { ImageUtils.picturePicked = file; }
- Откройте файл default.html и добавьте в него следующий скрипт. Он добавит ссылку на файл в новый файл JavaScript, imageUtils.js.
Этот код находится в файле \Module_6_Assets\snippets\includeImageUtils.txt
<!-- Add in the code to manage file pick --> <script src="/js/imageUtils.js"></script>
- Откройте файл JavaScript из /controls/addImageFlyout.js.
- Добавьте следующие строки кода в конец метода инициализации (Initialize), сразу после addEventListener нужно вызвать btnAddItem. Этот код сначала создаёт переменную btnSelectImage, которая ссылается на кнопку выбора изображения во всплывающем меню. Затем создаётся переменная btnAppBarAddImage, которая ссылается на кнопку AppBarCommand на панели приложения. Далее, свойство закрепления (sticky) устанавливается в значение "истина" для всплывающего меню, которое удерживает его открытым, пока пользователь выбирает изображение. И в конце необходимо установить событие для щелчка на кнопке btnSelectImage.
Этот код находится в файле \Module_6_Assets\snippets\includeImageUtils.txt
var btnSelectImage = document.getElementById("btnSelectImage"); var appbar = document.getElementById("appbar"); var btnAppBarAddImage = document.getElementById("btnAppBarAddImage"); appbar.winControl._sticky = true; btnAppBarAddImage.winControl.flyout._sticky = true;
- Запустите проект. Переведите в рабочее положение панель приложения и выберите Новый элементm (New Ite), затем нажмите на кнопку Выбор изображения (Select Image) . Нужно обратить внимание, что средство выбора файла используется для того, чтобы разрешить выбор файла. Далее вы будете сохранять выбранный файл.