Objective c 目标-C/可可当量的fread
我正在尝试读取文件的前四个字节。我知道这在以下C代码中正常工作:Objective c 目标-C/可可当量的fread,objective-c,c,cocoa,Objective C,C,Cocoa,我正在尝试读取文件的前四个字节。我知道这在以下C代码中正常工作: FILE *file = fopen(URL.path.UTF8String, "rb"); uint data; fread(&data, 4, 1, file); NSLog(@"%u", data); 这个打印出来:205 我试图找到在Objective-C/中使用Cocoa函数实现这一点的等效方法。我试过很多方法。我觉得以下几点很接近: NSFileHandle *fileHandle = [NSFileHand
FILE *file = fopen(URL.path.UTF8String, "rb");
uint data;
fread(&data, 4, 1, file);
NSLog(@"%u", data);
这个打印出来:205
我试图找到在Objective-C/中使用Cocoa函数实现这一点的等效方法。我试过很多方法。我觉得以下几点很接近:
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:URL error:nil];
NSData *data2 = [fileHandle readDataOfLength:4];
NSLog(@"%@", data2);
NSLog(@"%u", (uint)data2.bytes);
这将打印出:fread()
不会对数据做任何处理,您将获得文件中的字节
这完全是字节顺序造成的,但我对苹果的Objective C API:s一无所知。我不明白为什么不需要对data2
对象进行指针访问,甚至(为什么data2.bytes
没有失败,并且data2->bytes
需要?)
另外,NSData
的文档没有说明我可以找到的字节顺序。fread()
在二进制模式下对数据没有任何作用,您将获得文件中的字节
这完全是字节顺序造成的,但我对苹果的Objective C API:s一无所知。我不明白为什么不需要对data2
对象进行指针访问,甚至(为什么data2.bytes
没有失败,并且data2->bytes
需要?)
另外,
NSData
的文档没有说明我可以找到的字节顺序。您没有取消对数据的引用
NSLog(@"%u", (uint)data2.bytes); // wrong
“快速黑客”版本如下:
NSLog(@"%u", *(uint *) data2.bytes); // hack
更健壮的解决方案需要复制到某个地方的变量,以获得正确的对齐,但这并不影响所有平台:
uint value;
[data getBytes:&value length:sizeof(value)];
NSLog(@"%u", value);
另一种解决方案是逐字节显式读取数据,这是最可移植的,在任何平台上都没有对齐问题,在任何平台上都没有字节顺序问题:
unsigned char *p = data.bytes;
uint value = (unsigned) p[0] | ((unsigned) p[1] << 8) |
((unsigned) p[2] << 16) | ((unsigned) p[3] << 24);
NSLog(@"%u", value);
无符号字符*p=data.bytes;
uint value=(无符号)p[0]|((无符号)p[1]您没有取消对数据的引用
NSLog(@"%u", (uint)data2.bytes); // wrong
“快速黑客”版本如下:
NSLog(@"%u", *(uint *) data2.bytes); // hack
更健壮的解决方案需要复制到某个地方的变量,以获得正确的对齐,但这并不影响所有平台:
uint value;
[data getBytes:&value length:sizeof(value)];
NSLog(@"%u", value);
另一种解决方案是逐字节显式读取数据,这是最可移植的,在任何平台上都没有对齐问题,在任何平台上都没有字节顺序问题:
unsigned char *p = data.bytes;
uint value = (unsigned) p[0] | ((unsigned) p[1] << 8) |
((unsigned) p[2] << 16) | ((unsigned) p[3] << 24);
NSLog(@"%u", value);
无符号字符*p=data.bytes;
uint value=(unsigned)p[0]|((unsigned)p[1]您尝试将4字节的序列重新解释为unsigned int。这不能保证在所有平台上都有效。它仅在sizeof(unsigned int)等于4时有效。并且它仅在读取和写入的字节顺序相同时有效
此外,您没有使用NSLog正确打印标量。您试图将4个字节的序列重新解释为无符号整数。这并不能保证在所有平台上都有效。它仅在sizeof(无符号整数)等于4时有效。并且仅当读写字节顺序相同时才有效
此外,您没有使用NSLog正确打印标量。data2.bytes
是属性访问的Objective-C语法。data2.bytes
用于访问对象的属性;data2->bytes
将访问实例变量(请考虑结构成员),当且仅当您有权访问该实例变量时(默认情况下,ivar受保护,因此您只能在NSData实现中访问该ivar)。属性访问语法相当于消息表达式(方法调用):data2.bytes
=[data2 bytes]
data2.bytes
是属性访问的Objective-C语法。data2.bytes
用于访问对象的属性;data2->bytes
将访问实例变量(考虑结构成员),如果且仅当您有权访问该实例变量(ivar在默认情况下受保护,因此只有在NSData实现中才能访问该ivar)。属性访问语法相当于消息表达式(方法调用):data2.bytes
==[data2 bytes]
(等效)memcpy的替代方法:[data getBytes:&value-length:sizeof(value)]
“便携”代码示例应该考虑类型<代码> uTIN /代码>的大小。否则,它将彻底解释微妙的问题。@ CoujDead:“便携”解决方案是可移植地读取4字节整数,而不是可移植地读取<代码> UTEN<代码>。它是可移植的,因为<代码> UTEN/COD>保证至少4字节。(等效)MeMyPy的替代:<代码> [数据GETByth:&值长度:SIZEOF(值)] 。您的“便携”代码示例应考虑类型<代码> UTEN>代码>。否则,它将彻底解释微妙的问题。@ CoujDealth:“便携式”“解决方案是可移植读取4字节整数,而不是可移植读取uint
。它是可移植的,因为uint
保证至少有4个字节。@NikolaiRuhe是的,在使用bytes
属性的示例的第二部分中也是如此。”(我指的是样本的第一部分,其中uint由4个字节填充)@NikolaiRuhe是的,在样本的第二部分中,当