web-dev-qa-db-ja.com

NSDataをiPhoneでバイト配列に変換する方法は?

NSDataをバイト配列に変換したいので、次のコードを記述します。

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

しかし、コードの最後の行には、「割り当ての互換性のないタイプ」というエラーが表示されます。データをバイト配列に変換する正しい方法は何ですか?

45
Chilly Zhong

変数を使用して配列を宣言できないため、_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は回避されますが、拡張性が低く、バッファオーバーフローの問題が発生しやすいため、めったに使用しません。

59
Matt Gallagher

また、必要な型にキャストして、バイトを使用することもできます。

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

すでに答えましたが、他の読者を助けるために一般化するには:

    //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]);
    }
13
Khulja Sim Sim

_-[NSData bytes]_の署名は- (const void *)bytesです。スタック上の配列にポインターを割り当てることはできません。 NSDataオブジェクトで管理されているバッファーを配列にコピーする場合は、_-[NSData getBytes:]_を使用します。コピーせずに実行したい場合は、配列を割り当てないでください。ポインタ変数を宣言し、NSDataにメモリを管理させるだけです。

9
Nicholas Riley

これは、[データバイト]の戻り値の型がUint8(Byteのtypedefである)ではなく、void * cスタイルの配列だからです。

エラーは、戻り値がポインター型であるときに割り当てられた配列を設定しようとしているため、探しているのは、次のようなgetBytes:length:呼び出しです。

[data getBytes:&byteData length:len];

NSDataオブジェクトからのデータで割り当てた配列を埋めます。

Swiftに相当するものだと私は信じています:

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