Вход/Регистрация
Программирование на Objective-C 2.0
вернуться

Кочан Стивен

Шрифт:

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

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

Открыть файл и получить объект класса NSFileHandle для ссылки на этот файл в последующих операциях ввода-вы вода.

Выполнить необходимые операции ввода-вывода с открытым файлом.

Закрыть файл.

В таблице 16.6 приводятся некоторые наиболее распространенные методы NSFileHandle. В этой таблице fh — это объект NSFileHandle, data — это объект NSData, path — это объект NSString, offset — это значение типа unsigned long long. Метод Описание +(NSFileHandle *) fileHandleForReadingAtPath: path Открывает файл для чтения. +(NSFileHandle *) fileHandleFoiWritingAtPath: path Открывает файл для записи. +(NSFileHandle *) fileHandleForUpdatingAtPath: path Открывает файл для изменения (чтение и запись). -(NSData *) availableData Возвращает данные, доступные для чтения, из устройства или канала. -(NSData *) readDataToEndOfFile Читает оставшиеся данные до конца файла порциями не более (UINT_MAX) байт. -(NSData *) readDataOflength: (NSUInteger) bytes Читает заданное количество байтов {bytes) из файла. -(void) writeData: data Записывает данные (data) в файл. -(unsigned long long) offsetlnFite Получает текущее смещение в файле -(void) seekToFileOffset: offset Задает текущее смещение (offset) в файле. -(unsigned long long) seekToEndOfFile Помешает текущее смещение в конец файла. -(void) truncateFileAtOffset: offset Задает размер файла, равный o/fee/байт (с заполнением при необходимости свободного места). -(void) closeFile Закрывает файл.

Здесь не приводятся методы NSFileHandle для стандартного ввода, стандарт-ного вывода, стандартных ошибок и null-устройства. Они имеют форму fileHandleWithDevice, где обозначение Device может быть представлено как Standardlnput, StandardOutput, Standard Error или NullDevice.

Здесь также не приводятся методы для чтения и записи данных в фоновом режиме, то есть асинхронно.

Следует отметить, что класс FileHandle не предусматривает создание файлов. Это нужно делать с помощью методов FtleManager, которые были описаны выше. Например, в методах fileHandleForWritingAtPath: и fileHandleForUpdatingAlF’ath: предполагается, что файл существует, и они возвращают значение nil, если его нет. В обоих случаях смешение задастся в начале файла, поэтому запись (или чтение в режиме update) начинается с начала файла. Кроме того, если вы работали с UNIX, то, видимо, обратили внимание, что открытие файла для записи не вызывает усече-ния файла. Вы должны сделать это самостоятельно, если это вам нужно.

Программа 16.7 открывает исходный файл testfile, который мы создали в на-чале главы, читает его содержимое и копирует его в файл с именем testout. // Основные операции обработки файлов // Предполагается, что существует файл с именем "testfile" // в текущей рабочей папке #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/NSFileHandle.h> #import <Foundation/NSFileManager.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSData.h> int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSFileHandle *inFile, *outFile; NSData *buffer; // Открытие файла testfile для чтения inFile = [NSFileHandle fileHandleForReadingAtPath: @"testfile"]; if (inFile == nil) { NSLog (@"Open of testfile for reading failed"); (Невозможно открыть testfile для чтения) return 1; } // Создание выходного файла, если это нужно [[NSFileManager defaultManager] createFileAtPath: @"testout" contents: nil attributes: nil]; // Теперь открытие выходного файла для записи outFile = [NSFileHandle fileHandleForWritingAtPath: @"testout"]; if (outFile == nil) { NSLog (@"Open of testout for writing failed"); (Невозможно открыть testfile для записи) return 2; } // Усечение выходного файла, поскольку он может содержать данные [outFile truncateFileAtOffset: 0]; // Чтение данных из inFile и запись в outFile buffer = [inFile readDataToEndOfFile]; [outFile writeData: buffer]; // Закрытие обоих файлов [inFile closeFile]; [nutFilfi nloseFilfi]; // Проверка содержимого файла NSLog(@"%@", [NSString StringWithContentsOfFile: @"testout" encoding: NSUTF8StringEncoding error: nil]); [pool drain]; return 0; }

Вывод программы 16.7 This is a test file with some data in it. (Это тестовый файл с некоторыми данными.) Here’s another line of data. (Это еще одна строка данных.) And a third. (И третья.)

Метод readDataToEndOfFile: читает данные порциями не более UINT_MAX байт, что определено в и равно FFFFFFFF,6. Этого вполне достаточно для приложения, которое требуется написать. Мы можем также разбить эту работу для чтения и записи небольшими порциями и задать цикл для единовременной пересылки полного буфера между файлами с помощью метода readDataOfLength:. Например, размер буфера можно задать равным 8192 (8 кбайт) или 131072 (128 кбайт). Как правило, размер равен степени 2, поскольку базовая операционная система обычно выполняет свои операции ввода-вывода именно такими порциями данных. Вы можете опробовать различные значения, чтобы определить, что лучше в вашей системе.

Если метод чтения обнаруживает конец файла без чтения каких-либо данных, он возвращает пустой объект NSData (то есть буфер, не содержащий никаких данных). Мы можем применять к буферу метод length и проверять его на равенство нулю, чтобы определить, остались ли какие-то данные для чтения из файла.

Если мы открываем файл для изменения, смешение устанавливается на начало файла. Это смешение можно изменить путем поиска внутри файла и затем выполнить в файле операции чтения или записи. Например, для поиска 10-го байта в файле с описателем databaseHandle можно написать в сообщении следующее выражение. [databaseHandle seekToFileOffset: 10];

Для указания относительных позиций в файле нужно получитьтекущее сме-щение в файле и затем добавлять или вычитать из него относительное смещение. Например, чтобы пропустить следующие 128 байтов в файле, нужно написать следующее. [databaseHandle seekToFileOffet: [databaseHandle offsetlnFile] + 128];

Для смещения на пять целых данных в файле можно написать следующее. [databaseHandle seekToFileOffet: [databaseHandle offsetlnFile] - 5 * sizeof (int)];

Программа 16.8 добавляет содержимое одного файла ко второму. Второй файл открывается для записи, выполняется поиск конца этого файла и затем содержимое первого файла записывается во второй. // Добавление содержимого файла "fileA" в конец файла "fileB" #import <Foundation/NSObject.h> #import <Foundation/NSString.h> #import <Foundation/NSFileHandle.h> #import <Foundation/NSFileManager.h> #import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSData.h> int main (int argc, char *argv[]) { NSAutoreleasePool * poo) = [[NSAutoreleasePool alloc] init]; NSFileHandle *inFile, *outFile; NSData *buffer; // Открытие файла fileA для чтения inFile = [NSFileHandle fileHandleForReadingAtPatti: @"fileA*']; if (inFile == nil) { NSLog (@"Open of fileA for reading failed"); return 1; } // Открытие файла fileB для изменения outFile = [NSFileHandle fileHandleForWritingAtPath: @"fileB"]; if (outFile == nil) { NSLog (@"Open of fileB for writing failed"); return 2; } // Поиск конца outFile [outFile seekToEndOfFile]; // Чтение inFile и запись его содержимого в outFile buffer = [inFile readDataToEndOfFile]; [outFile writeData: buffer]; // Закрытие обоих файлов [inFile closeFile]; [outRle closeFile]; [pool drain]; return 0; }

Содержимое FileA перед запуском программы 16.8 This is line 1 in the first file. (Это строка 1 в первом файле) This is line 2 in the first file. (Это строка 2 в первом файле)

Содержимое FileB перед запуском программы 16.8 This is line 1 in the second file. (Это строка 1 во втором файле) This is line 2 in the second file. (Это строка 2 во втором файле)

Вывод программы 16.8 Contents of fileB (Содержимое fileB) This is line 1 in the second file. This is line 2 in the second file. This is line 1 in the first file. This is line 2 in the first file.

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

Внесите изменения в программу копирования (программа 16.6), чтобы она допускала более одного исходного файла для копирования в папку, аналогично стандартной команде UNIX ср. Например, команда $ copy copyl .m filel .т file2.m progs должна копировать три файла (copyl.m, filel.m и file2.m) в папку progs. Предусмотрите, что если указано более одного файла, то последним аргументом на самом деле является существующая папка.

  • Читать дальше
  • 1
  • ...
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: