web-dev-qa-db-fra.com

Comment convertir NSData en tableau d'octets sur iPhone?

Je veux convertir NSData en un tableau d'octets, donc j'écris le code suivant:

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

Mais la dernière ligne de code affiche une erreur indiquant "types incompatibles dans l'affectation". Quelle est alors la bonne façon de convertir les données en tableau d'octets?

45
Chilly Zhong

Vous ne pouvez pas déclarer un tableau à l'aide d'une variable, donc Byte byteData[len]; Ne fonctionnera pas. Si vous souhaitez copier les données d'un pointeur, vous devez également mémoriser (qui parcourra les données pointées par le pointeur et copiera chaque octet jusqu'à une longueur spécifiée).

Essayer:

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

Ce code allouera dynamiquement le tableau à la bonne taille (vous devez free(byteData) lorsque vous avez terminé) et copiera les octets dedans.

Vous pouvez également utiliser getBytes:length: Comme indiqué par d'autres si vous souhaitez utiliser un tableau de longueur fixe. Cela évite malloc/free mais est moins extensible et plus sujet aux problèmes de débordement de tampon, donc je ne l'utilise que rarement.

59
Matt Gallagher

Vous pouvez également simplement utiliser les octets où ils se trouvent, en les convertissant selon le type dont vous avez besoin.

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

Déjà répondu, mais pour généraliser pour aider les autres lecteurs:

    //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

La signature de -[NSData bytes] Est - (const void *)bytes. Vous ne pouvez pas affecter un pointeur à un tableau de la pile. Si vous souhaitez copier le tampon géré par l'objet NSData dans le tableau, utilisez -[NSData getBytes:]. Si vous voulez le faire sans copier, alors n'allouez pas de tableau; déclarez simplement une variable de pointeur et laissez NSData gérer la mémoire pour vous.

9
Nicholas Riley

C'est parce que le type de retour pour [octets de données] est un tableau de style void * c, pas un Uint8 (ce pour quoi Byte est un typedef).

L'erreur est parce que vous essayez de définir un tableau alloué lorsque le retour est un type de pointeur, ce que vous recherchez est l'appel getBytes: length: qui ressemblerait à:

[data getBytes:&byteData length:len];

Qui remplit le tableau que vous avez alloué avec les données de l'objet NSData.

Voici ce que je crois être l'équivalent Swift:

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