Шрифт:
При работе с файлами часто требуется читать данные во временную область хранения в памяти, которую называют буфером (buffer). Буфер часто использу-ется при сборе данных для последующего вывода в файл. Класс Foundation NSData позволяет легко создавать буфер, читать в него содержимое файла или писать содержимое буфера в файл. Для 32-битного приложения в буфере NSDATA можно хранить до 2 Гб. В случае 64-битного приложения в таком буфере можно хранить до 8 Эб (экзабайт), то есть 8000 Гб информации!
Можно определять немутабельные (NSData) или мутабельные (NSMutableData) области памяти. Мы ознакомим вас с методами данного класса в этой главе, а также в последующих главах.
В программе 16.2 показано, как читать содержимое файла в буфер, опреде-ленный в памяти.
Эта программа читает содержимое файла newftle2 и записывает его в новый файл с именем newfile3. В некотором смысле это реализация операции копиро-вания файла, хотя и не столь простая, как метод copy Rath :to Path: handler:, // Создание копии файла #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/NSFileManager.h> #import <Foundation/NSAutoreteasePool.h> #import <Foundation/N5Data.h> int main (int arge, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] initj; NSFileManager *fm; NSData *fileData; fm = [NSFileManager defaultManager]; // Чтение файла newfile2 fileData = [fm contentsAtPath: @"newfile2"]; if (fileData == nil) { NSLog (@"File read failed!"); return 1; } // Запись данных в newfile3 if ([fm createFileAtPath: @"newfile3" contents; fileData attributes: nil] == N0} { NSLog (@"Couldn’t create the copy!"); (Невозможно создать копию.) return 2; } NSLog (@"File copy was successful!"); (Копирование файла выполнено успешно) [pool drain]; return 0; }
Вывод программы 16.2 File copy was successful! (Копирование файла выполнено успешно)
Метод NSData contentsAtPath: просто принимает имя пути и читает содержимое указанного файла в область памяти (которую он создает). Метод возвращает в качестве результата объект области памяти или nil, если операцию чтения не удается выполнить (например, если этот файл не существует или недоступен для чтения).
Метод createRleAtPath:соntents:attributes: создает файл с указанными атрибутами (или использует атрибуты по умолчанию, если для аргумента атрибутов указано значение nil). Затем содержимое указанного объекта NSData записывается в файл. В нашем примере эта область памяти содержит данные прочитанного ранее файла. Работа с папками
В таблице 16.2 приводятся методы NSFileManager для работы с папками (катало-гами). Многие из этих методов аналогичны методам для обычных файлов из таблицы 16.1 (обозначения такие же, как в таблице 16.1).
Табл. 16.2. Наиболее распространенные методы Метод Описание– (NSString *) currentDirectoryPath Получает текущую папку. -(BOOL) changeCurrentDirectoryPath: path Изменяет текущую папку. -(BOOL) copyPath: from toPath: to handler: handler Копирует структуру папки (to не может существовать заранее). -(BOOL) createDirectoryAtPath: path attributes: attr Создает новую папку. -(BOOL) fileExistsAtPath: path isDirectory: (BOOL *) flag Проверяет, содержится ли данный файл в папке (результат YES/NO сохраняется в переменной flag). -(NSArray *) directoryContentsAtPath: path Создает список содержимого папки. -(NSDirectoryEnumerator *) enumeratorAtPath: path Перечисляет содержимое папки. -(BOOL) removeFileAtPath: path handler: handler Удаляет пустую папку -(BOOL) movePath: from toPath: to handler: handler Переименовывает или перемещает папку (to не может существовать заранее).
В программе 16.3 показаны основные операции с папками. // Основные операции с папками #import <Foundation/NSObject.h> #import <Foundation/NSSIring.h> #import <Foundation/NSFileManager.h> #import <Foundation/NSAutoreleasePool.h> int main (int argc, char *argv[]) { NSAutoreleasePooi * pool = [[NSAutoreleasePool alloc] init]; NSString *dirName = @"testdir"; NSString *path; NSFileManager *fm; // Нужно создать экземпляр filemanager fm = [NSFileManager defaultManager]; // Получение текущей папки path = [fm currentDirectoryPath]; NSLog (@"Current directory path is %@", path); (Путь к текущей папке) // Создание новой папки if ([fm createDirectoryAtPath: dirName attributes: nil] == NO) { NSLog ((@"Couldn’t create directory!"); (Невозможно создать папку) return 1; } // Переименование новой папки if ((fm movePath: dirName toPath: @"newdir" handler: nil] == NO) { NSLog {@Directory rename failed!"); return 2; } // Смена папки на другую папку if ([fm changeCurrentDirectoryPath: @newdir"] == NO) { NSLog (@Change directory failed!"); (Невозможно сменить папку) return 3; } // Получение и вывод пути к текущей рабочей папке path = [fm currentDirectoryPath]; NSLog (@"Current directory path is %@", path); (Путь к текущей папке) NSLog (@"All operations were successful!"); (Все операции выполнены успешно) [pool drain]; return 0; }
Вывод программы 16.3 Current directory path is /Users/stevekochan/progs/ch16 (Путь к текущей папке) Current directory path is /Users/stevekochan/progs/ch16/newdir All operations were successful! (Все операции выполнены успешно)
Работу программы 16.3 легко понять из текста самой программы. Сначала мы получаем путь к текущей папке для информативных целей. Затем в текущей папке создается новая папка testdir. Затем в программе используется метод movePath:toPath:handler: для переименования этой новой папки из testdir в newdir. Помните, что этот метод позволяет также перемещать всю структуру папки (включая ее содержимое) из одного места файловой системы в другое.
После переименования новой папки программа делает эту новую папку те-кущей с помощью метода changeCurrentDirectoryPath:. Затем выводится путь к текущей папке, чтобы убедиться, что изменение было выполнено успешно. Перечисление содержимого папки
Получил! список содержимого папки. Этот процесс можно осуществить с по-мощью метода enumeratorAtPath: или directoryContentsAtPath:. В первом случае каждый файл указанной папки перечисляется по отдельности, Если один из этих файлов является папкой, то по умолчанию его содержимое тоже рекурсивно перечисляется. Во время этого процесса мы можем динамически запрещать рекурсию (отправив сообщение skipDescendants объекту перечисления), чтобы содержимое папки не перечислялось.
В случае метода directoryContentsAtPath: выполняется перечисление указанной папки, и метод возвращает массив со списком. Если какой-либо из этих файлов является папкой, его содержимое не перечисляется данным методом. В программе 16.4 показано, как использовать каждый из этих методов. // Перечисление содержимого папки #import <Foundation/NSString.h> #import <Foundation/NSFileManager.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSArray.h> int main (int argc, char *argv[]) { NSAutoreteasePool * pool = [[NSAutoreleasePool alloc] initj; NSString *path; NSFileManager *fm; NSDirectoryEnumerator *dirEnum; NSArray *dirArray; // Создание экземпляра filemanager fm = [NSFileManager defaultManager]; // Получение пути к текущей рабочей папке path = [fm currentDirectoryPath]; // Перечисление содержимого папки dirEnum = [fm enumeratorAtPath: path]; NSLog (@"Contents of path"); (Содержимое папки) while ((path = [dirEnum nextObject]) != nil) NSLog (@"%@", path); // Еще один способ перечисления содержимого папки dirArray = [fm directoryContentsAtPath: [fm currentDirectoryPath]]; NSLog (@"Contents using directoryContentsAtPath:"); (Содержимое с помощью ...) for (path in dirArray) NSLog (@"%@", path); [pool drain]; return 0; }