Пара вопросов по NSFileHandle, Obj-C - PullRequest
0 голосов
/ 05 ноября 2010

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

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

NSFileHandle * sourceFile;

NSData * d1;

NSString * st1, * st2 = @ "";

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

для (int i = 0; i <500; i ++) {</p>

d1 = [sourceFile readDataOfLength: 20];

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

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

st1 = @ "";

}

[sourceFile closeFile];

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

Ответы [ 2 ]

1 голос
/ 13 марта 2012

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

0 голосов
/ 26 августа 2011

Чтобы получить размер файла, вы можете просто использовать 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
   䠀 │     攀 │    氀 │    氀 │  ?

Чтобы это работало, просто убедитесь, что вы всегда устанавливаете четное смещение для обработчика файла перед чтением и что вы всегда читаете четное число байтов.

...