Как вы извлекаете байты из файла в простые типы данных? - PullRequest
1 голос
/ 10 декабря 2010

Я перепробовал все, что мог придумать и не могу заставить что-либо работать. У меня есть двоичный файл, который я написал в 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 ]

1 голос
/ 10 декабря 2010

ОК, что-то действительно странное происходит с моими данными.Я только что посмотрел на необработанные значения байтов в Visual C ++ и Objective-C, и они совсем не согласны.Я только читаю первые четыре байта файла и смотрю на их значения.На данный момент я предполагаю, что я не правильно их читаю, но я не знаю, чего мне здесь не хватает.Код Visual C ++, который я использую для просмотра значений байтов, приведен ниже:

ifstream input("c:\\out.ipv", ios::in | ios::binary);
Byte tmp[4];
input.read((char*)&tmp[0], 4);

Значения в массиве tmp:

76
248
6
0

Если я делаю то же самое вtarget-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);

ничего не делает.Любые идеи, почему он не читает из файла, как это должно быть?

ЗАКЛЮЧИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ:

ОК, я, вероятно, не должен публиковать ответ на этот вопрос, так как это заставляет меня выглядеть очень глупо, но яне хочу, чтобы кто-то читал эти посты, чтобы запутаться.Таким образом, массивы и объекты всегда возвращали одни и те же значения, несмотря ни на что, что также оказалось теми значениями, которые они имели при распределении.У меня было слишком много. В моем имени файла, поэтому он пытался прочитать в out..ipv, а не в out.ipv.Как только я исправил имя файла, все заработало именно так, как я ожидал.Извините за путаницу, и спасибо всем за помощь.

1 голос
/ 10 декабря 2010

Это звучит как проблема с порядком байтов.Вы можете использовать любую из функций в <libkern/OSByteOrder.h> для чтения данных с указанным порядком байтов.В вашем случае вы можете захотеть сделать что-то вроде

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
}
...