Доступ к файлам и каталогам

Прежде чем можно будет открыть файл, сначала необходимо определить местоположение его в файловой системе. Системные платформы обеспечивают много подпрограмм для получения ссылок на многие известные каталоги, такой как Library каталог и его содержание. Можно также указать расположения вручную путем создания URL или основанного на операция со строками пути от известных имен каталогов.

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

Выберите правильный способ получить доступ к файлам

Несмотря на то, что можно открыть любой файл и считать его содержание, поскольку поток байтов, делая так является не всегда правильным выбором. OS X и iOS предоставляют встроенную поддержку, делающую открытие многих типов стандартных форматов файлов (таких как текстовые файлы, изображения, звуки и списки свойств) намного проще. Для этих стандартных форматов файлов необходимо использовать высокоуровневые опции для чтения и записи содержания файла. Таблица 2-1 перечисляет типы общего файла, поддерживаемые системой вместе с информацией о том, как Вы получаете доступ к ним.

Табличные 2-1  Типы файлов со специализированными подпрограммами

 Тип файла

Примеры               

Описание

Файлы ресурсов

Файлы пера

Файлы образа

Звуковые файлы

Строковые файлы

Локализованные ресурсы

Приложения используют файлы ресурсов, чтобы хранить данные, которые независимы от кода, использующего их. Файлы ресурсов обычно используются для хранения локализуемого содержания, такого как строки и изображения. Процесс для чтения данных из файла ресурсов зависит от типа ресурса.

Для получения информации о том, как считать содержание файлов ресурсов, см. Руководство по программированию Ресурса.

Текстовые файлы

Файл простого текста

UTF-8 отформатировал файл

UTF-16 отформатировал файл

Текстовый файл является неструктурированной последовательностью символов ASCII или Unicode. Вы обычно загружаете содержание текстового файла в NSString возразите, но может также считать и записать текстовый файл как необработанный поток символов.

Для получения информации об использовании NSString класс для загрузки текста из файла см. Строковое Руководство по программированию.

Файлы структурированных данных

XML-файл

Файл списка свойств

Предпочтительный файл

Файл структурированных данных обычно состоит из основанных на операция со строками данных, расположенных с помощью ряда специальных символов.

Для получения информации о парсинге XML см. Событийно-управляемое Руководство по программированию XML.

Архивные файлы

Двоичные файлы создали использование включенного объекта archiver

Архив является форматом файла, используемым для хранения персистентной версии объектов периода выполнения приложения. Объект archiver кодирует состояние объектов в поток байтов, которые могут быть записаны в диск одновременно. unarchiver инвертирует процесс, с помощью потока байтов, чтобы воссоздать объекты и восстановить их к их предыдущему состоянию.

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

Для получения информации о том, как создать и считать архивные файлы, видит Руководство по программированию Архивов и Сериализации.

Пакеты файла

Пользовательские форматы документов

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

Пакеты

Приложения

Плагины

Платформы

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

Для получения информации о пакетах и как Вы получаете доступ к ним, см. Руководство по программированию Пакета

Файлы кода

Ресурсы двоичного кода

Динамические совместно используемые библиотеки

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

Для получения информации о том, как загрузить ресурсы кода в память, посмотрите, что Код Загружает Темы Программирования.

Обертка файла

Набор файлов, появляющихся как единственный файл

Приложения используют обертки файла, чтобы хранить файлы способом, который может быть записан сериализированным способом, который может использовать используемый с областью монтажа или сохраненный как часть Вашей записи данных. Посмотрите Используя FileWrappers как Контейнеры Файла для получения дополнительной информации об обертках файла.

В ситуациях, где стандартные форматы файлов недостаточны, можно всегда создавать собственные форматы файлов. При чтении и записи содержания пользовательских файлов, Вы читаете и пишете данные как поток байтов и применяете те байты к связанным с файлом структурам данных своего приложения. Вы имеете полный контроль над тем, как Вы читаете и пишете байты и как Вы управляете своими связанными с файлом структурами данных. Для получения дополнительной информации о методах для чтения и записи файлов, использующих пользовательские форматы файлов, посмотрите Методы для Чтения и Записи Файлов Без Координаторов Файла.

Указание пути к файлу или каталогу

Предпочтительный способ указать расположение файла или каталога состоит в том, чтобы использовать NSURL класс. Несмотря на то, что NSString класс имеет много методов, связанных с созданием тракта, URLs предлагает более устойчивый способ определить местоположение файлов и каталогов. Для приложений, также работающих с сетевыми ресурсами, URLs также означает, что можно использовать один тип объекта управлять элементами, расположенными в локальной файловой системе или в сетевом сервере.

Для большей части URLs Вы создаете URL путем конкатенации имен каталогов и имен файлов вместе с помощью надлежащего NSURL методы, пока у Вас нет пути к элементу. URL, созданный таким образом, упоминается как находящийся на пути URL, потому что это хранит имена, должен был пересечь иерархию каталогов для определения местоположения элемента. (Вы также создаете основанные на операция со строками пути путем конкатенации каталога и имен файлов вместе с результатами, сохраненными в немного отличающемся формате, чем используемый NSURL класс.) В дополнение к находящемуся на пути URLs, можно также создать ссылку на файл URL, идентифицирующий расположение файла или каталога с помощью уникального идентификатора.

Все следующие записи являются действительными ссылками к вызванному файлу MyFile.txt в пользователе Documents каталог:

Находящийся на пути URL: file://localhost/Users/steve/Documents/MyFile.txt

Ссылка на файл URL: file:///.file/id=6571367.2773272/

Основанный на операция со строками путь: /Users/steve/Documents/MyFile.txt

Различные файловые системы полагаются на различные символы разделителя. Из-за этих изменений необходимо создать объекты URL с помощью методов, предоставленных классом NSURL.

Вы создаете объекты URL с помощью NSURL методы и преобразовывают их в ссылку на файл URLs только при необходимости. Находящимся на пути URLs проще управлять, проще отладить, и обычно предпочитается классами такой как NSFileManager. Преимущество ссылки на файл, которая URLs - то, что они менее хрупки, чем находящийся на пути URLs, в то время как работает Ваше приложение. Если пользователь перемещает файл в Средство поиска, любой находящийся на пути URLs, относящийся к файлу сразу, становится недопустимым и должен быть обновлен к новому пути. Однако пока файл, перемещенный в другое расположение на том же диске, его уникальный идентификатор не изменяется и никакая ссылка на файл, URLs остается допустимым.

Конечно, когда Вы, возможно, должны были бы использовать строки для обращения к файлу, существуют все еще времена. К счастью, NSURL класс обеспечивает методы для преобразования находящегося на пути URLs в и от NSString объекты. Вы могли бы использовать основанный на операция со строками путь при представлении того пути к пользователю или при вызове системной подпрограммы, принимающей строки вместо URLs. Преобразование между NSURL объекты и NSString объекты сделаны с помощью метода класса NSURL absoluteString.

Поскольку NSURL и NSString опишите только расположение файла или каталога, можно создать их, прежде чем будет существовать фактический файл или каталог. Никакой класс не пытается проверить фактическое существование файла или каталога, который Вы указываете. Фактически, необходимо создать путь к несуществующему файлу или каталогу, прежде чем можно будет создать его на диске.

Для получения дополнительной информации о методах Вы используете, чтобы создать и управлять URLs и строками, видеть Ссылку класса NSURL и Ссылку класса NSString.

Определение местоположения элементов в файловой системе

Прежде чем можно будет получить доступ к файлу или каталогу, необходимо знать его расположение. Существует несколько способов определить местоположение файлов и каталогов:

Файловые системы iOS и OS X налагают определенные инструкции по тому, куда необходимо поместить файлы, так большинство элементов приложение создает, или использование должно быть сохранено в известном месте. Обе системы обеспечивают интерфейсы для определения местоположения элементов в таких известных местах, и Ваше приложение может использовать эти интерфейсы для определения местоположения элементов и путей сборки к определенным файлам. Приложение должно предложить пользователю указывать расположение файла или каталога только в ограниченном количестве ситуаций, описанных в Использовании Открытого и Сохраняющих Панели.

Выяснение, чтобы пользователь определил местоположение элемента

В OS X взаимодействие с пользователем с файловой системой должно всегда быть через стандартные панели Open и Save. Поскольку эти панели включают прерывание пользователя, необходимо использовать их только в ограниченном количестве ситуаций:

  • Открыть пользовательские документы

  • Спросить пользователя, где сохранить новый документ

  • К файлам ассоциированного пользователя (или каталоги файлов) с открытым окном

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

Для получения информации о том, как представить и настроить панели Open и Save, видит Используя Открытое и Сохраняет Панели.

Определение местоположения элементов в комплекте приложений

Приложения, которые должны определить местоположение файлов ресурсов в их каталоге пакета (или в другом известном пакете) должны сделать настолько использующий NSBundle объект. Пакеты избавляют от необходимости Ваше приложение помнить расположение отдельных файлов путем организации тех файлов в особенном методе. Методы NSBundle класс понимает, что организация и использует его для определения местоположения ресурсов приложения по требованию. Преимущество этого метода состоит в том, что можно обычно перестраивать содержание пакета, не переписывая код, который Вы используете для доступа к нему. Пакеты также используют в своих интересах настройки языка текущего пользователя для определения местоположения соответственно локализованной версии файла ресурсов.

Следующий код показывает, как получить объект URL для названного изображения MyImage.png это расположено в основном пакете приложения. Этот код определяет только расположение файла; это не открывает файл. Вы передали бы возвращенный URL методу NSImage класс для загрузки изображения из диска так, чтобы Вы могли использовать его.

NSURL* url = [[NSBundle mainBundle] URLForResource:@"MyImage" withExtension:@"png"];

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

Определение местоположения элементов в стандартных каталогах

Когда необходимо будет определить местоположение файла в одном из стандартных каталогов, используйте системные платформы, чтобы определить местоположение каталога сначала и затем использовать получающийся URL для создания пути к файлу. Платформа Основы включает несколько опций для определения местоположения стандартных системных каталогов. При помощи этих методов пути будут корректны, поигралось ли Ваше приложение в песочнице или нет:

  • URLsForDirectory:inDomains: метод NSFileManager класс возвращает расположение каталога, упакованное в NSURL объект. Каталог для поиска NSSearchPathDirectory постоянный. Эти константы обеспечивают URLs для корневого каталога пользователя, а также большинства стандартных каталогов.

  • NSSearchPathForDirectoriesInDomains функция ведет себя как URLsForDirectory:inDomains: метод, но возвраты расположение каталога как основанный на операция со строками путь. Необходимо использовать URLsForDirectory:inDomains: метод вместо этого.

  • NSHomeDirectory функционируйте возвращает путь или к корневому каталогу пользователя или к приложения. (Какой корневой каталог возвращается, зависит от платформы и является ли приложение в песочнице.), Когда приложение поигралось в песочнице точки корневого каталога к песочнице приложения, иначе это указывает на корневой каталог Пользователя в файловой системе. При построении файла к подкаталогу корневого каталога пользователя необходимо вместо этого рассмотреть использование URLsForDirectory:inDomains: метод вместо этого.

Можно использовать URL или находящуюся на пути строку, которую Вы получаете от предыдущих подпрограмм для создания новых объектов с расположениями файлов, которые Вы хотите. Оба NSURL и NSString классы обеспечивают связанные с путем методы для добавления и удаления компонентов контура и внесения изменений в путь в целом. Перечисление 2-1 показывает пример, ищущий стандарт Application Support каталог и создает новый URL для каталога, содержащего файлы данных приложения.

Перечисление 2-1  , Создающее URL для элемента в каталоге поддержки приложений

- (NSURL*)applicationDataDirectory {
    NSFileManager* sharedFM = [NSFileManager defaultManager];
    NSArray* possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory
                                 inDomains:NSUserDomainMask];
    NSURL* appSupportDir = nil;
    NSURL* appDirectory = nil;
 
    if ([possibleURLs count] >= 1) {
        // Use the first directory (if multiple are returned)
        appSupportDir = [possibleURLs objectAtIndex:0];
    }
 
    // If a valid app support directory exists, add the
    // app's bundle ID to it to specify the final directory.
    if (appSupportDir) {
        NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
        appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID];
    }
 
    return appDirectory;
}

Определение местоположения файлов Используя закладки

Если Вы хотите сохранить расположение файла постоянно, используйте возможности закладки NSURL. Закладка является непрозрачной структурой данных, включенной в NSData объект, описывающий расположение файла. Принимая во внимание, что путь - и ссылка на файл, URLs потенциально хрупок между запусками Вашего приложения, закладка, может обычно использоваться для воссоздавания URL к файлу даже в случаях, куда файл был перемещен или переименован.

Для создания закладки для существующего URL используйте bookmarkDataWithOptions:includingResourceValuesForKeys:relativeToURL:error: метод NSURL. Указание NSURLBookmarkCreationSuitableForBookmarkFile опция создает NSData объект, подходящий для того, чтобы сохранить на диск. Перечисление 2-2 показывает простую реализацию в качестве примера, использующую этот метод для создания объекта данных закладки.

Перечисление 2-2  , Преобразовывающее URL в персистентную форму

- (NSData*)bookmarkForURL:(NSURL*)url {
    NSError* theError = nil;
    NSData* bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationSuitableForBookmarkFile
                                            includingResourceValuesForKeys:nil
                                            relativeToURL:nil
                                            error:&theError];
    if (theError || (bookmark == nil)) {
        // Handle any errors.
        return nil;
    }
    return bookmark;
}

Если Вы пишете персистентные данные закладки в диск с помощью writeBookmarkData:toURL:options:error: метод NSURL, то, что система создает на диске, является файлом псевдонима. Псевдонимы подобны символьным ссылкам, но реализованы по-другому. Обычно, пользователи создают псевдонимы из Средства поиска, когда они хотят создать ссылки к файлам в другом месте в системе.

Для преобразования объекта данных закладки назад в URL используйте URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error: метод NSURL. Перечисление 2-3 показывает процесс для преобразования закладки назад в URL.

Перечисление 2-3  Возвращая персистентную закладку ее форме URL

- (NSURL*)urlForBookmark:(NSData*)bookmark {
    BOOL bookmarkIsStale = NO;
    NSError* theError = nil;
    NSURL* bookmarkURL = [NSURL URLByResolvingBookmarkData:bookmark
                                            options:NSURLBookmarkResolutionWithoutUI
                                            relativeToURL:nil
                                            bookmarkDataIsStale:&bookmarkIsStale
                                            error:&theError];
 
    if (bookmarkIsStale || (theError != nil)) {
        // Handle any errors
        return nil;
    }
    return bookmarkURL;
}

Базовая платформа Основы обеспечивает ряд функций на базе С, которые параллельны интерфейсу закладки, предоставленному NSURL. Для получения дополнительной информации об использовании тех функций см. Ссылку CFURL.

Перечисление содержания каталога

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

Перечисление каталога один файл за один раз

Перечисление каталога, который за один раз рекомендуется один файл, когда Вы хотите искать определенный файл и прекратить перечислять при нахождении его. Перечисление файла файлом использует NSDirectoryEnumerator класс, определяющий методы для получения элементов. Поскольку NSDirectoryEnumerator самостоятельно абстрактный класс, однако, Вы не создаете экземпляры его непосредственно. Вместо этого Вы используете любого enumeratorAtURL:includingPropertiesForKeys:options:errorHandler: или enumeratorAtPath: метод NSFileManager объект получить конкретный экземпляр класса для использования в Вашем перечислении.

Объекты перечислителя возвращают пути всех файлов и каталогов, содержавших в перечислимом каталоге. Поскольку перечисления являются рекурсивными и перекрестными границами устройств, число файлов и каталогов возвратилось, могут быть больше, чем, что присутствует в начальном каталоге. Можно пропустить содержание любого каталога, которым Вы не интересуетесь путем вызова объекта перечислителя skipDescendents метод. Объекты перечислителя не разрешают символьные ссылки или попытку пересечь символьные ссылки та точка к каталогам.

Перечисление 2-4 показывает, как использовать enumeratorAtURL:includingPropertiesForKeys:options:errorHandler: метод для перечисления всех видимых пользователем подкаталогов данного каталога, отмечая, являются ли они пакетами файла или каталогами. keys массив говорит объекту перечислителя выбрать с упреждением и кэшировать информацию для каждого элемента. Упреждающая выборка этой информации повышает эффективность путем касания диска только один раз. Параметр опций указывает, что перечисление не должно перечислять содержание пакетов файла и скрытых файлов. Обработчик ошибок является блочным объектом, возвращающим булево значение. Если возвращается блок YES, перечисление продолжается после ошибки; если это возвращается NO, остановки перечисления.

Перечисление 2-4  , Перечисляющее содержание каталога

NSURL *directoryURL = <#An NSURL object that contains a reference to a directory#>;
 
NSArray *keys = [NSArray arrayWithObjects:
    NSURLIsDirectoryKey, NSURLIsPackageKey, NSURLLocalizedNameKey, nil];
 
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager]
                                     enumeratorAtURL:directoryURL
                                     includingPropertiesForKeys:keys
                                     options:(NSDirectoryEnumerationSkipsPackageDescendants |
                                              NSDirectoryEnumerationSkipsHiddenFiles)
                                     errorHandler:^(NSURL *url, NSError *error) {
                                         // Handle the error.
                                         // Return YES if the enumeration should continue after the error.
                                         return <#YES or NO#>;
                                     }];
 
for (NSURL *url in enumerator) {
 
    // Error checking is omitted for clarity.
 
    NSNumber *isDirectory = nil;
    [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:NULL];
 
    if ([isDirectory boolValue]) {
 
        NSString *localizedName = nil;
        [url getResourceValue:&localizedName forKey:NSURLLocalizedNameKey error:NULL];
 
        NSNumber *isPackage = nil;
        [url getResourceValue:&isPackage forKey:NSURLIsPackageKey error:NULL];
 
        if ([isPackage boolValue]) {
            NSLog(@"Package at %@", localizedName);
        }
        else {
            NSLog(@"Directory at %@", localizedName);
        }
    }
}

Можно использовать другие методы, объявленные NSDirectoryEnumerator определить атрибуты файлов во время перечисления — обоих из родительского каталога и текущего файла или каталога — и управлять рекурсией в подкаталоги. Код в Перечислении 2-5 перечисляет содержание каталога и перечисляет файлы, измененные в течение прошлых 24 часов; если, однако, это сталкивается с пакетами файла RTFD, это пропускает рекурсию в них.

Перечисление 2-5  Ища файлы, недавно измененные

NSString *directoryPath = <#Get a path to a directory#>;
NSDirectoryEnumerator *directoryEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:directoryPath];
 
NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:(-60*60*24)];
 
for (NSString *path in directoryEnumerator) {
 
    if ([[path pathExtension] isEqualToString:@"rtfd"]) {
        // Don't enumerate this directory.
        [directoryEnumerator skipDescendents];
    }
    else {
 
        NSDictionary *attributes = [directoryEnumerator fileAttributes];
        NSDate *lastModificationDate = [attributes objectForKey:NSFileModificationDate];
 
        if ([yesterday earlierDate:lastModificationDate] == yesterday) {
            NSLog(@"%@ was modified within the last 24 hours", path);
        }
    }
}

Получение содержания каталога в работе единого пакета

Если Вы знаете, что хотите смотреть на каждый элемент в каталоге, можно получить снимок элементов и выполнить итерации по ним когда вам будет удобно. Получение содержания каталога в пакетной обработке не является самым эффективным способом перечислить каталог, потому что файловый менеджер должен идти, весь каталог удовлетворяет каждый раз. Однако, если Вы планируете смотреть на все элементы так или иначе, это - намного более простой способ получить элементы.

Существует две опции для того, чтобы сделать пакетное перечисление использования каталога NSFileManager:

Перечисление 2-6 показывает пример, использующий contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error: метод для перечисления содержания каталога. Одно из преимуществ использования URLs - то, что можно также эффективно получить дополнительную информацию о каждом элементе. Этот пример получает локализованное имя, дату создания и информацию о типе для каждого элемента в каталоге и хранит ту информацию в соответствии NSURL объект. Когда метод возвращается, можно продолжить для итерации по элементам в array переменная и делает то, в чем Вы нуждаетесь с ними.

Перечисление 2-6  , Получающее список элементов в каталоге одновременно

NSURL *url = <#A URL for a directory#>;
NSError *error = nil;
NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey,
                          NSURLCreationDateKey, NSURLLocalizedTypeDescriptionKey, nil];
 
NSArray *array = [[NSFileManager defaultManager]
                   contentsOfDirectoryAtURL:url
                   includingPropertiesForKeys:properties
                   options:(NSDirectoryEnumerationSkipsHiddenFiles)
                   error:&error];
if (array == nil) {
    // Handle the error
}

Определение, где хранить специфичные для приложения файлы

Library каталог является определяемым репозиторием для файлов, которые Ваше приложение создает и управляет от имени пользователя. Необходимо полагать, что эти каталоги могут быть в различных расположениях, если приложение поигралось в песочнице. В результате необходимо всегда использовать NSFileManager метод URLsForDirectory:inDomains: с NSUserDomainMask как домен для определения местоположения определенного каталога, который необходимо использовать, чтобы хранить эти данные.

Подсказки для доступа к файлам и каталогам

Поскольку файловая система является ресурсом, совместно использованным всеми процессами, включая системные процессы, необходимо всегда использовать ее тщательно. Даже в системах с дисками твердотельного диска, операции файла имеют тенденцию быть немного медленнее из-за задержки, вовлеченной в получение данных от диска. И когда Вы действительно получаете доступ к файлам, важно, чтобы Вы сделали так в пути, который безопасен и не вмешивается в другие процессы.

Выполните операции файла лениво

Операции, включающие файловую систему, должны быть выполнены только, когда они абсолютно необходимы. Доступ к файловой системе обычно занимает много времени относительно других задач всего компьютера. Поэтому удостоверьтесь, что действительно необходимо получить доступ к диску, прежде чем Вы сделаете. В частности:

  • Запишите данные в диск только, когда у Вас будет что-то ценное для сохранения. Определение того, что ценно, отличается для каждого приложения, но должно обычно включать информацию, которую пользователь предоставляет явно. Например, если Ваше приложение создает некоторые структуры данных по умолчанию во время запуска, Вы не должны сохранять те структуры на диск, если пользователь не изменяет их.

  • Считайте данные из диска только при необходимости в нем. Другими словами, загрузите данные, в которых Вы нуждаетесь для своего пользовательского интерфейса теперь, но не загружаете весь файл только для получения одной маленькой части данных от того файла. Для пользовательских форматов файлов используйте отображение файла или только для чтения несколько блоков файла, что необходимо представить пользовательский интерфейс. Считайте любые остающиеся блоки по мере необходимости в ответ на взаимодействие с пользователем с данными. Для форматов структурированных данных используйте Базовые Данные, чтобы управлять и оптимизировать чтение данных для Вас.

Используйте безопасные методы кодирования

Существует несколько принципов, за которыми можно следовать, чтобы помочь гарантировать, чтобы у Вас не было основанных на файле уязвимостей системы обеспечения безопасности в Вашей программе:

  • Проверьте коды результата на любые функции или методы, которые Вы вызываете. Коды результата должны там сообщить, что существует проблема, таким образом, необходимо обратить внимание на них. Например, при попытке удалить каталог, что Вы думаете, пусто, и получите код ошибки, Вы могли бы найти, что каталог не пуст, в конце концов.

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

  • Каждый раз, когда подпрограммы возможного применения, воздействующие на дескрипторы файлов, а не пути. Таким образом можно быть уверены, что Вы всегда имеете дело с тем же файлом.

  • Преднамеренно создайте файлы как отдельный шаг от открытия их так, чтобы можно было проверить открытие файла, который Вы создали, а не уже существовавший тот

  • Знайте, идет ли функция, которую Вы вызываете, по символьным ссылкам. Например, lstat функция дает Вам состояние файла независимо от того, является ли это нормальным файлом или символьной ссылкой, но stat функция идет по символьным ссылкам и, если указанный файл был символьной ссылкой, возвращает состояние соединенного - к файлу. Поэтому, если Вы используете stat функция, Вы могли бы получать доступ к различному файлу, чем Вы ожидали.

  • Перед чтением файла удостоверьтесь, что файл имеет владельца и полномочия, которые Вы ожидаете. Будьте подготовлены перестать работать корректно (вместо того, чтобы зависнуть), если это не делает.

  • Установите маску создания кода файла своего процесса (umask) для ограничения доступа к файлам, создаваемым процессом. umask является битовой маской, изменяющей полномочия по умолчанию нового файла. Вы не сбрасываете umask для своего приложения, Ваш процесс наследовал umask от своего родительского процесса. Для получения дополнительной информации об установке umask, посмотрите umask(2) OS X Developer Tools Manual Page.

Для дополнительных подсказок и методов кодирования, посмотрите Условия состязания и Защитите Операции Файла в Безопасном Руководстве по Кодированию.

Примите чувствительность к регистру для путей

При поиске или сравнении имен файлов, всегда предполагайте, что базовая файловая система чувствительна к регистру. OS X поддерживает много файловых систем что вариант использования для дифференциации между файлами. Даже в файловых системах (таких как HFS +), что нечувствительность случая поддержки, существуют все еще времена, когда случай может использоваться для сравнения имен файлов. Например, NSBundle класс и APIs CFBundle рассматривают случай при поиске каталогов пакета именованные ресурсы.

Включайте расширения файла для новых файлов

Все файлы должны иметь расширение файла, отражающее тип содержания, содержавшегося в файле. Расширения файла помогают системе определить, как открыть файлы и также упростить обмениваться файлами с другими компьютерами или другими платформами. Например, сетевые программы передачи часто используют расширения файла для определения лучшего пути к передать файлы между компьютерами.

Используйте имена дисплея при представлении элементов

Каждый раз, когда необходимо представить имя файла или каталога в пользовательском интерфейсе, всегда используйте имя дисплея элемента. Используя дисплей имя гарантирует что, что Ваше приложение представляет соответствия, что представляют Средство поиска и другие приложения. Например, если Ваше приложение показывает, что путь к файлу, с помощью имени дисплея гарантирует, что путь локализуется в соответствии с настройками языка текущего пользователя.

Для получения дополнительной информации об именах дисплея, посмотрите Файлы, и Каталоги Могут Иметь Альтернативные названия.

Доступ к файлам безопасно от фоновых потоков

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

  • Избегайте использования того же дескриптора файла от многократных потоков. Выполнение так могло заставить каждый поток разрушать состояние другого.

  • Всегда используйте координаторов файла для доступа к файлам. Когда другие потоки в Вашей программе (или другие процессы) получают доступ к тому же файлу, координаторы файла обеспечивают уведомления. Можно использовать эти уведомления, чтобы очистить локальные структуры данных или выполнить другие соответствующие задачи.

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