Телефон: 8-800-350-22-65
WhatsApp: 8-800-350-22-65
Telegram: sibac
Прием заявок круглосуточно
График работы офиса: с 9.00 до 18.00 Нск (5.00 - 14.00 Мск)

Статья опубликована в рамках: XLI Международной научно-практической конференции «Научное сообщество студентов XXI столетия. ТЕХНИЧЕСКИЕ НАУКИ» (Россия, г. Новосибирск, 26 апреля 2016 г.)

Наука: Информационные технологии

Скачать книгу(-и): Сборник статей конференции

Библиографическое описание:
Каменева А.Е., Горбунова А.В. РЕШЕНИЕ ПРОБЛЕМЫ ОПРЕДЕЛЕНИЯ СУЩЕСТВОВАНИЯ ФАЙЛА В WINRT-ПРИЛОЖЕНИЯХ // Научное сообщество студентов XXI столетия. ТЕХНИЧЕСКИЕ НАУКИ: сб. ст. по мат. XLI междунар. студ. науч.-практ. конф. № 4(40). URL: https://sibac.info/archive/technic/4(40).pdf (дата обращения: 25.11.2024)
Проголосовать за статью
Конференция завершена
Эта статья набрала 267 голосов
Дипломы участников
Диплом лауреата
отправлен участнику

РЕШЕНИЕ ПРОБЛЕМЫ ОПРЕДЕЛЕНИЯ СУЩЕСТВОВАНИЯ ФАЙЛА В WINRT-ПРИЛОЖЕНИЯХ

Каменева Анастасия Евгеньевна

студент 1 курса, кафедра физической химии и химической технологии МГТУ им. Носова, г. Магнитогорск

Горбунова Алина Викторовна

студент 1 курса, кафедра физической химии и химической технологии МГТУ им. Носова, г. Магнитогорск

Каменева Галина Анатольевна

научный руководитель,

кандидат педагогических наук, доцент МГТУ им. Носова,

г. Магнитогорск

Интерфейс работы с файлами в WinRT-приложениях представлен классами StorageFolder и StorageFile. Класс StorageFolder управляет папками и их содержимым, а также предоставляет сведения о них [1,140 c.]. Класс StorageFile, в свою очередь, представляет файл, сведения о файле и его содержимом, а также способы работы с ними.

На практике возникла следующая задача: необходимость загрузки большого количества файлов по заданному строкой пути, при условии, что файлы и папки, в которых они должны находиться, могут как существовать, так и отсутствовать. Таким образом, необходимо иметь в распоряжении некоторую функцию, способную определить существование файла и аналогичную для папки. Классы StorageFolder и StorageFile таких функций не предусматривают. Далее рассмотрим возможные решения данной проблемы.

Поиск показал, что данную проблему можно решить несколькими способами. Очевидным решением кажется использовать непосредственно функцию StorageFile.GetFileFromPathAsync(string path). Данная функция при существовании файла возвращает объект StorageFile, а при его отсутствии на диске вызывает исключение FileNotFoundException. Суть решения в том, чтобы создать булевую функцию, которая на вход принимает строку, содержащую путь к файлу, а далее пытается получить файл при помощи StorageFile.GetFileFromPathAsync() и вернуть true. В случае исключения FileNotFoundException функция должна вернуть false.

async Task<bool> isExists1(string path) {

try {

StorageFile file = await StorageFile.GetFileFromPathAsync(path);

return true;

}

catch (FileNotFoundException e) {

return false;

}

};

Минусом данного решения является скорость работы полученной функции. Обработка исключения занимает довольно ощутимое время [2, c.540]. Если функция вызывается для достаточно большого количества файлов, многие из которых не существуют, наблюдается сильное замедление работы приложения.

Вторым решением является проверка файла на существование при помощи LINQ-запроса.

async Task<bool> isExists2 (string path) {

            try {

          var folderPath = Path.GetDirectoryName(path);

          var fileName = Path.GetFileName(path);

          StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(folderPath);

 

return (await folder.GetFilesAsync()).Any(x => x.Name.Equals(fileName));

            }

            catch (FileNotFoundException e) {

                return false;

            }

 catch (ArgumentException e)  {

      return false;

  }

}

Данный метод работает немного быстрее предыдущего, так как исключения возникают реже – нет вызова функции StorageFile.GetFileFromPathAsync, т.е. код не пытается обратиться непосредственно к файлу. Однако, исключение возникнет при попытке обратиться к несуществующей папке.

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

Для хранения списка папок и файлов в них используем классы стандартного пространства имен System.Collections – Dictionary и List. Dictionary представляет собой словарь, в котором хранятся пары ключ-значение. List – класс, представляющий односвязный список. Создадим словарь, ключом которого является имя папки, а значением – список имен файлов в ней.

Dictionary <string, List<string>> folderList = new Dictionary <string, List<string>> ();

Каждый файл, поступающий в функцию, будем обрабатывать следующим образом: при помощи класса Path получим имя директории, в которой находится файл. Далее проверим, добавлена ли эта директория в кэш: если да, то ищем имя файла в кэше. На этом этапе используются исключительно функции для манипуляции коллекциями (Contains, Add). Если имя директории не было найдено в кэше, то необходимо добавить туда директорию и список содержащихся в ней файлов. Здесь для получения списка файлов в директории нужно будет использовать функцию StorageFolder.GetFolderFromPathAsync (string path), которая может вызвать исключение при обращении к несуществующей папке. Это исключение перехватывается, и в словарь добавляется пара с ключом-названием папки и null в качестве значения – это будет значить, что папка не существует. Также перехватывается исключение ArgumentException, которое возникает, если на вход функции подается некорректная строка. Если такое произошло, то функция вернет false.

public static async Task<bool> CheckFile(string path) {

    try  {

        var folderPath = Path.GetDirectoryName(path);

        var fileName = Path.GetFileName(path);

        if (folderList.ContainsKey(folderPath)) {

            return folderList[folderPath].Contains(fileName);

        }

        else  {

            try {

                StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(folderPath);

                var storageFileList = await folder.GetFilesAsync();

                List<string> fileList = new List<string>();

                foreach (var file in storageFileList)  {

                    fileList.Add(Path.GetFileName(file.Path));

                }

                folderList.Add(folderPath, fileList);

                return fileList.Contains(fileName);

            }

            catch (FileNotFoundException e) {

                folderList.Add(folderPath, new List<string>());

                return false;

            }

        }

    }

    catch (ArgumentException e) {

        return false;

    }

}

Подобный подход нельзя считать общим и использовать как однозначную альтернативу для первых двух способов. Однако, такое решение позволяет обрабатывать большое число файлов, находящихся в одной или нескольких папках с минимум исключений, так как обращение к каждой папке как к StorageFolder производится единожды (и только в этот момент может возникнуть исключение), а обращения собственно к файлам как к StorageFile не производится вообще. Использование данного способа в применении к поставленной задаче дает ощутимый прирост производительности по сравнению с первыми двумя решениями.

 

Список литературы:

  1. Пугачев С.В. Разработка приложений для Windows 8 на языке C# / С. В. Пугачев, А. М. Шериев, К. А. Кичинский. — СПб.: БХВ-Петербург, 2013. — 416 с.
  2. Рихтер Дж. CLR via C#. Программирование на платформе Microsoft .NET Framework 2.0 на языке C#. Мастер-класс. / Пер. с англ. — 2-е изд., исправ. — М.: Издательство «Русская Редакция»; СПб.: Питер , 2008. — 656 стр.: ил.
Проголосовать за статью
Конференция завершена
Эта статья набрала 267 голосов
Дипломы участников
Диплом лауреата
отправлен участнику

Оставить комментарий

Форма обратной связи о взаимодействии с сайтом
CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.