Пара вопросов по NSFileHandle, Obj-C

Сейчас я работаю над Obj-C с файлами, мое приложение должно читать некоторые огромные текстовые файлы (например, 5 МБ), которые имеют кодировку символов UTF16. Первая проблема заключается в том, как определить размер файла, который я собираюсь читать из ?

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

NSFileHandle *исходный файл;

НСДата *d1;

NSString *st1,*st2 = @;

sourceFile = [NSFileHandle fileHandleForReadingAtPath: filePath]; // размер моего файла 5 МБ

для (целое я = 0; я ‹ 500; я ++) {

d1 = [исходный файл readDataOfLength: 20];

st1 = [[NSString alloc] initWithData: d1 encoding: NSUTF16StringEncoding]; // преобразование моих необработанных данных в строку UTF16

st2 = [st2 stringByAppendingFormat:@%@,st1];

ст1 = @;

}

[исходный файл закрыть файл];

после этого st2 будет содержать некоторую строку, и эта строка будет иметь какой-то четкий символ (как в исходном файле), но тогда она будет содержать беспорядок непонятных символов (например, 䠆⠆䀆䀆䀆ㄆ䌆✆⨆䜆) .. всю ночь не спал пытался разобраться, но не смог :(


person ObjProg    schedule 05.11.2010    source источник


Ответы (2)


@Neovibrant: извините за ошибку, но UTF-16 не всегда составляет 2 байта (или 16 бит) на символ. Как вы видите в статье в Википедии, это может быть 4 байта для всех символов выше U+10000 ... Таким образом, будет недостаточно следить за четным смещением, потому что вы можете обрезать 4-байтовый символ этим. Лучший способ всегда использовать правильную кодировку и предоставить файловому менеджеру определять размер символа.

person Hamster    schedule 13.03.2012

Чтобы получить размер файла, вы можете просто использовать NSFileManager:

NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:filePath error:nil];
unsigned long long size = [fileAttributes fileSize];

Вторая проблема связана с кодировкой UTF-16. Видите ли, в UTF-16 символ представлен 2+ байтами (http://en.wikipedia.org/wiki/UTF-16).

Предположим, у вас есть текстовый файл в кодировке UTF-16 с текстом Hello. Байты будут:

00 48 │ 00 65 │ 00 6C │ 00 6C │ 00 6F
   H  │    e  │     l │     l │     o

Все хорошо, если вы начнете читать с байта 0 (или любого четного индекса), вы получите ожидаемый результат. Но вы начинаете читать с нечетного байта (например, 1), все символы будут испорчены, потому что байты сдвинуты:

48 00 │ 65 00 │ 6C 00 │ 6C 00 │ 6F
   䠀 │     攀 │    氀 │    氀 │  ?
person Neovibrant    schedule 26.08.2011