سؤال

أريد تحويل NSData إلى صفيف بايت، لذلك أكتب التعليمات البرمجية التالية:

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

لكن السطر الأخير من التعليمات البرمجية ينبثق خطأ يقول "أنواع غير متوافقة في التعيين". ما هي الطريقة الصحيحة لتحويل البيانات إلى صفيف بايت إذن؟

هل كانت مفيدة؟

المحلول

لا يمكنك إعلان صفيف باستخدام متغير ذلك 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 ولكنه أقل قابل للتوسيع وأكثر عرضة للقضايا الفائضة العازلة لذلك نادرا ما استخدمته.

نصائح أخرى

يمكنك أيضا استخدام البايتات حيث تكون، يلقيها بالنوع الذي تحتاجه.

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

أجاب بالفعل، ولكن التعميم لمساعدة القراء الآخرين:

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

توقيع -[NSData bytes] يكون - (const void *)bytes. وبعد لا يمكنك تعيين مؤشر إلى صفيف على المكدس. إذا كنت ترغب في نسخ المخزن المؤقت يديره NSData الاعتراض في الصفيف، واستخدام -[NSData getBytes:]. وبعد إذا كنت ترغب في القيام بذلك دون نسخ، فلا تخصيص صفيف؛ فقط أعلن متغير مؤشر واسمحوا NSData إدارة الذاكرة بالنسبة لك.

ذلك لأن نوع الإرجاع ل [بايت البيانات] هو صفيف باطلة نمط C، وليس UINT8 (وهو ما البايت هو typedef for).

الخطأ هو أن تحاول أن تحاول ضبط صفيف مخصص عند الإرجاع نوع مؤشر، ما تبحث عنه هو GetBytes: الطول: الاتصال الذي سيبدو وكأنه:

[data getBytes:&byteData length:len];

الذي يملأ الصفيف الذي قمت بتخصيصه بالبيانات من كائن NSDATA.

إليك ما أعتقده هو المكافئ السريع:

if let data = NSData(contentsOfFile: filePath) {
   let length = data.length
   let byteData = malloc(length)
   memcmp(byteData, data.bytes, length)
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top