如何在 iPhone 中将 NSData 转换为字节数组?

Posted

技术标签:

【中文标题】如何在 iPhone 中将 NSData 转换为字节数组?【英文标题】:How to convert NSData to byte array in iPhone? 【发布时间】:2010-10-17 23:14:06 【问题描述】:

我想将NSData转换为字节数组,所以我写了如下代码:

NSData *data = [NSData dataWithContentsOfFile:filePath];
int len = [data length];
Byte byteData[len];
byteData = [data bytes];

但是最后一行代码弹出一个错误,说“分配中的类型不兼容”。 那么将数据转换为字节数组的正确方法是什么?

【问题讨论】:

【参考方案1】:

您不能使用变量声明数组,因此Byte byteData[len]; 将不起作用。如果要从指针复制数据,还需要memcpy(它会遍历指针指向的数据,并将每个字节复制到指定长度)。

试试:

NSData *data = [NSData dataWithContentsOfFile:filePath];
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);

此代码将动态分配数组到正确的大小(完成后您必须free(byteData))并将字节复制到其中。

如果您想使用固定长度的数组,您也可以使用getBytes:length:,正如其他人所指出的那样。这避免了 malloc/free,但扩展性较差,更容易出现缓冲区溢出问题,因此我很少使用它。

【讨论】:

字节 byteData = malloc(len);弹出一个警告说“初始化从没有强制转换的指针中生成整数”。并且 byteData 原来是一个字节变量,而不是一个字节数组。对此有何想法? 代码中有一个小错字,现在应该可以正常工作了。 是的。 memcpy的第二个参数应该是[data bytes]。 @matt Gallagher:它工作正常,但这种转换会造成一些延迟。如何减少...任何想法???? Byte byteData[len] 将与 Clang 和 GCC 一起使用。这是有效的 C(C 支持可变长度数组),因此也是有效的 Objective-C。【参考方案2】:

您也可以只使用它们所在的字节,将它们转换为您需要的类型。

unsigned char *bytePtr = (unsigned char *)[data bytes];

【讨论】:

这样做,我得到一个“可变大小的对象可能没有被初始化”的错误 再一次,测试表明只有第一个字节的数据会被复制到bytePtr:bytePtr[1]、bytePtr[2]等包含0;【参考方案3】:

已经回答,但概括一下以帮助其他读者:

    //Here:   NSData * fileData;
    uint8_t * bytePtr = (uint8_t  * )[fileData bytes];

    // Here, For getting individual bytes from fileData, uint8_t is used.
    // You may choose any other data type per your need, eg. uint16, int32, char, uchar, ... .
    // Make sure, fileData has atleast number of bytes that a single byte chunk would need. eg. for int32, fileData length must be > 4 bytes. Makes sense ?

    // Now, if you want to access whole data (fileData) as an array of uint8_t
    NSInteger totalData = [fileData length] / sizeof(uint8_t);

    for (int i = 0 ; i < totalData; i ++)
    
        NSLog(@"data byte chunk : %x", bytePtr[i]);
    

【讨论】:

【参考方案4】:

-[NSData bytes] 的签名是- (const void *)bytes。您不能将指针分配给堆栈上的数组。如果要将NSData 对象管理的缓冲区复制到数组中,请使用-[NSData getBytes:]。如果您想在不复制的情况下进行操作,则不要分配数组;只需声明一个指针变量,让NSData 为您管理内存。

【讨论】:

添加后 [data getBytes:byteData length:len]; byteData 原来是无效的。可能是什么问题? 尝试打印 NSData 并查看是否匹配;然后检查长度并确保它看起来像您期望的那样。如果数据是字符串,也可以试试 -[NSString stringWithContentsOfFile]。 我发现了问题:长度不应该是一个变量。应该是 Byte byteData[255]; Java 最近对我来说太多了。 :-) 很高兴你明白了。【参考方案5】:

这是因为 [data bytes] 的返回类型是 void* c 样式数组,而不是 Uint8(这是 Byte 的 typedef)。

错误是因为您试图在返回是指针类型时设置分配的数组,您正在寻找的是 getBytes:length: 调用,它看起来像:

[data getBytes:&byteData length:len];

用来自 NSData 对象的数据填充您分配的数组。

【讨论】:

字节数据无效。可能是什么问题? @ChillyZhong 尝试指定 byteData 大小,例如 uint8_t *cipherBuffer[16] 然后删除 &amp; 和 NSLog(@"%s", (char *)byteData);【参考方案6】:

这是我认为的 Swift 等价物:

if let data = NSData(contentsOfFile: filePath) 
   let length = data.length
   let byteData = malloc(length)
   memcmp(byteData, data.bytes, length)

【讨论】:

以上是关于如何在 iPhone 中将 NSData 转换为字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

在Objective C(可可)中将十六进制数据字符串转换为NSData

如何在 Swift 3 中将 NSData 转换为数据?

在obj-c中将NSData加密为NSString?

将UIImage转换为NSData并在Swift中转换回UIImage?

如何在iPhone开发中将地址转换为纬度和经度[重复]

如何在 iphone sdk 中将 NSArray/NSMutableArray 转换为 NSFetchedResultsController?