كيف يمكنك استخراج البايت من ملف إلى أنواع بيانات بسيطة؟
-
25-09-2019 - |
سؤال
لقد جربت كل ما يمكنني التفكير فيه ولا يمكنني الحصول على أي شيء للعمل. لديّ ملف ثنائي كتبته في vb.net والذي يتكون أساسًا من عدد صحيح ، (في ثنائي بالطبع) يخبرني بحجم الصفيف للبيانات التالية ، ثم العوامات كبيانات ثنائية. يكتب الملف على ما يرام من VB.NET ، ويمكنني قراءته مرة أخرى من خلال Visual C ++ على ما يرام باستخدام الكود التالي:
ifstream output("c:\\out.ipv", ios::in | ios::binary);
UInt32 len;
UInt32 *ptr2 = (UInt32*)&len;
output.read((char*)ptr2, 4);
هذا يعيد القيمة الصحيحة البالغة 456780 ، البايتات هي: 76 ، 248 ، 6 ، 0. عندما أقوم بتشغيل نفس الرمز بالضبط على جهاز iPad الخاص بي ، أحصل على 1043089572. إذا استخدمت الطريقة البديلة أدناه:
NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];
UInt32 num;
const NSRange numV = {0, 4};
[data getBytes:&num range:numV];
يعيد هذا الرمز قيمة مختلفة ، 124724 ، ولست متأكدًا من كيفية قراءة ما هي البايتات الدقيقة التي يتم سحبها من الملف. هذا شيء آخر كنت أحاول اكتشافه ولكن لم أستطع العمل. أي فكرة لماذا نفس الطريقة التي تعمل في Visual C ++ لن تعمل على iPad؟ أنا حقا في حيرة من هذا.
المحلول 2
حسنًا ، هناك شيء غريب حقًا يجري مع بياناتي. لقد نظرت للتو إلى قيم البايت الخام في كل من Visual C ++ و Objective-C ، ولا يوافقون على الإطلاق. أنا أقرأ فقط البايتات الأربعة الأولى من الملف وأبحث في قيمها. أفترض في هذه المرحلة أنني لا أقرأها بشكل صحيح ، لكنني لا أعرف ما الذي أفتقده هنا. يقع رمز C ++ المرئي الذي أستخدمه للنظر في قيم البايت أدناه:
ifstream input("c:\\out.ipv", ios::in | ios::binary);
Byte tmp[4];
input.read((char*)&tmp[0], 4);
القيم في صفيف TMP هي:
76
248
6
0
إذا فعلت نفس الشيء في الهدف-C:
ifstream input([filePath UTF8String], ios::in | ios::binary);
Byte tmp[4];
input.read((char*)&tmp[0], 4);
انا حصلت:
164
72
44
62
ما يعطي؟ كان من المتوقع على الأقل الحصول على نفس قيم البايت. الملف الذي يحتوي على البايتات الأربعة التي أواجه مشكلة معها هنا: newout1.ipv
تعديل:
أدركت أين تأتي قيم البايت 164،72،44،62 من: هذه هي القيم العميقة التي تحتوي عليها صفيف البايت قبل أن أضع أي شيء فيه. لسبب ما الخط:
input.read((char*)&tmp[0], 4);
لا تفعل أي شيء. أي أفكار لماذا لا تقرأ من الملف كما ينبغي؟
التحرير النهائي:
حسنًا ، ربما لا ينبغي عليّ نشر الإجابة على هذا لأنه يجعلني أبدو غبيًا حقًا ، لكنني لا أريد أي شخص يقرأ هذه المنشورات للارتباك. لذا ، كانت المصفوفات والأشياء تعود دائمًا إلى نفس القيم بغض النظر عن ما حدث ، وهو ما حدث أيضًا من القيم التي كانت لديهم عندما تم تخصيصها. كان لدي الكثير. بمجرد إصلاح اسم الملف ، عمل كل شيء بالضبط كيف توقعت ذلك. آسف على الارتباك ، وشكرا على مساعدة الجميع.
نصائح أخرى
هذا يبدو وكأنه قضية إنديان. يمكنك استخدام أي من الوظائف في <libkern/OSByteOrder.h>
لقراءة البيانات في endianness محددة. في حالتك ، قد ترغب في فعل شيء مثل
NSInputStream *istream = [NSInputStream inputStreamWithFileAtPath:filePath];
UInt32 num = 0;
if (istream) {
uint8_t buffer[4];
if ([istream read:buffer maxLength:4] == 4) {
num = OSReadLittleInt32(buffer, 0);
} else {
// there weren't 4 bytes in the file
}
} else {
// the file could not be opened
}