关于NSFileHandle,Obj-C的几个问题

时间:2010-11-05 10:04:13

标签: objective-c encoding nsfilehandle

我现在正在使用带文件的Obj-C,我的应用程序应该读取一些具有UTF16字符编码的大文本文件(例如5 MB)。 第一个问题是如何检测我要读取的文件大小?

第二个问题是当我只读一次文件时它给了我正确的文字,但是当我试图寻找或读取另一个时间时,它就不会给我原始文本,这是我的代码段:

  

NSFileHandle * sourceFile;

     

NSData * d1;

     

NSString * st1,* st2 = @“”;

     

sourceFile = [NSFileHandle fileHandleForReadingAtPath:filePath]; //我的文件大小是5 MB

     

for(int i = 0; i< 500; i ++){

     

d1 = [sourceFile readDataOfLength:20];

     

st1 = [[NSString alloc] initWithData:d1 encoding:NSUTF16StringEncoding]; //将我的原始数据转换为UTF16字符串

     

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

     

st1 = @“”;

     

}

     

[sourceFile closeFile];

执行此操作后,st2将携带一些字符串,此字符串将具有一些清晰的字符(如原始文件中所示),但随后它将带有一堆不清楚的字符(例如䠆⠆䀆䀆䀆ㄆ䌆✆ ⨆⨆)..我整晚都没有睡觉试图搞清楚,但不能:(

2 个答案:

答案 0 :(得分:1)

@Neovibrant: 抱歉,你错了,但每个字符的UTF-16并不总是2字节(或16位)。正如您在维基百科文章中看到的那样,对于U + 10000以上的所有字符,它可以是4个字节... 因此,注意偶数偏移是不够的,因为你可以截断一个4字节的字符。 最好的方法是始终使用正确的编码并将其留给文件管理器来确定字符的大小。

答案 1 :(得分:0)

要获取文件大小,您只需使用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
   䠀 │     攀 │    氀 │    氀 │  ?

要使其工作,只需确保在读取之前始终为文件处理程序设置偶数偏移量,并且始终读取偶数个字节。