Пара вопросов по NSFileHandle, Obj-C
Сейчас я работаю над Obj-C с файлами, мое приложение должно прочитать несколько огромных текстовых файлов (например, 5 МБ) с кодировкой символов UTF16. Первая проблема заключается в том, как определить размер файла, который я собираюсь читать с?
Вторая проблема - когда я читаю файл только один раз, он дает мне правильный текст, но когда я пытаюсь искать или читать в другой раз, он не даст мне мой исходный текст, а вот мой фрагмент кода:
NSFileHandle * sourceFile;
NSData * d1;
NSString * st1, * st2 = @ "";
sourceFile = [NSFileHandle fileHandleForReadingAtPath: filePath]; // размер моего файла 5 МБ
для (int i = 0; i <500; i ++) {
d1 = [sourceFile readDataOfLength: 20];
st1 = [[NSString alloc] initWithData: d1 кодировка:NSUTF16StringEncoding]; // преобразование моих необработанных данных в строку UTF16
st2 = [st2 stringByAppendingFormat: @ "% @", st1];
st1 = @ "";
}
[sourceFile closeFile];
после того, как это выполнено, тогда st2 будет нести некоторую строку, и эта строка будет иметь некоторый четкий символ (как в исходном файле), но тогда он будет нести беспорядок нечетких символов (например, 䠆⠆䀆䀆䀆ㄆ䌆✆⨆䜆).. Я не спал всю ночь, пытаясь понять это, но не мог:(
2 ответа
@Neovibrant: Извините, что прошу вас неправильно, но UTF-16 не всегда 2 байта (или 16 бит) на символ. Как вы видите в статье в википедии, это может быть 4 байта для всех символов выше U+10000 ... Так что будет недостаточно следить за четным смещением, потому что вы можете усечь 4-байтовый символ этим. Лучше всего всегда использовать правильную кодировку и оставить ее для файлового менеджера, чтобы определить размер символа.
Чтобы получить размер файла, вы можете просто использовать 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
䠀 │ 攀 │ 氀 │ 氀 │ ?
Чтобы это работало, просто убедитесь, что вы всегда устанавливаете четное смещение для обработчика файла перед чтением, и что вы всегда читаете четное число байтов.