2016-12-27 12 views
3

Я читаю кучу битовых значений из текстового файла, который находится в двоичном формате, потому что я сохранил их с помощью fwrite. Проблема в том, что первое значение в файле имеет размер 5 байт, а следующие 4800 - 2 байта. Поэтому, когда я пытаюсь выполнить цикл через файл и прочитать значения, это даст мне неправильные результаты, потому что моя программа не знает, что она должна принимать 5 байтов в первый раз, а затем 2 байта, оставшихся 4800 раз.Как вы можете читать значения битов разных размеров из файла?

Вот как я на велосипеде через файл:

long lSize; 
unsigned short * buffer; 
size_t result; 

pFile = fOpen("dataValues.txt", "rb"); 

lSize = ftell(pFile); 

buffer = (unsigned short *) malloc (sizeof(unsigned short)*lSize);  
size_t count = lSize/sizeof(short); 



for(size_t i = 0; i < count; ++i) 
{ 
    result = fread(buffer+i, sizeof(unsigned short), 1, pFile); 
    print("%u\n", buffer[i]); 
} 

Я уверен, что я собираюсь нужно изменить свое fread заявление, потому что первое значение имеет тип time_t, так что я буду вероятно, нужно заявление, что выглядит следующим образом:

result = fread(buffer+i, sizeof(time_t), 1, pFile); 

Однако это не сработало работу, когда я попробовал это, и я думаю, что это потому, что я не изменяя исходное положение должным образом. Я думаю, что пока я читаю 5 байт данных, я не перемещаю исходную позицию достаточно.

У кого-нибудь есть хорошее представление о fread? Не могли бы вы сообщить мне, что я могу изменить, чтобы моя программа выполнила то, что мне нужно.

EDIT:

Это, как я пишу в файл.

fwrite(&timer, sizeof(timer), 1, pFile); 
fwrite(ptr, sizeof(unsigned short), rawData.size(), pFile); 

EDIT2:

Я попытался прочитать файл, используя ifstream

int main() 
{ 
    time_t x; 
    ifstream infile; 
    infile.open("binaryValues.txt", ios::binary | ios::in); 
    infile.read((char *) &x, sizeof(x)); 
    return 0; 
} 

Однако, теперь он не компилируется и просто дать мне кучу undefined reference to ошибок в коде, Я даже не написал.

+0

Это может быть полезно разместить код, используемый для хранения данных.Также вы читаете этот файл с другой машины, которая его написала? – Galik

+0

Нет такой же машины, и я добавил код 'fwrite'. Это довольно стандартно. Я просто беру некоторые значения из QVector и записываю их в файл. –

+0

Код, используемый для хранения данных, выглядит как C++? Значит, это должно быть помечено C++? – cat

ответ

0

Вы не можете. Потоки байт, почти всегда октет (8 бит) ориентированы.

Вы можете легко создать потоки с битовой ориентацией поверх этого. Вы просто сохраняете несколько байтов в буфере и отслеживаете, какой бит является текущим. Следите за тем, чтобы получить последние несколько бит, и пытается смешивать доступ к байту с битным доступом.

Непрошеный, но это общая идея.

struct bitstream 
    { 
     unsigned long long rack; // 64 bits rack 
     FILE *fp;     // file opened for reading 
     int rackpos;    // 0 - 63, poisition of bits read. 
    } 

    int getbits(struct bitstream *bs, int Nbits) 
    { 
    unsigned long long mask = 0x8000 0000 0000 0000; 
    int answer = 0; 

    while(bs->rackpos > 8) 
    { 
     bs->rack <<= 8; 
     bs->rack |= fgetc(bs->fp); 
     bs->rackpos -= 8; 
    } 
    mask >>= bs->rackpos; 
    for(i=0;i<Nbits;i++) 
    { 
     answer <<= 1; 
     answer |= bs->rack & mask; 
     mask >>= 1; 
    } 
    bs->rackpos += Nbits; 

    return answer; 
    } 

Вам необходимо решить, как вы знаете, когда поток прекращается. Как вы можете испортить последние несколько бит с EOF, прочитанным fgetc().

+0

Извините, но я полный C++ noob, вы можете объяснить, что вы имеете в виду? Есть ли еще способ для меня выполнить то, что мне нужно? Как нет способа, чтобы я мог отличить значение 'time_t' от значения' unsigned_short'? –

2

Я не вижу проблемы:

uint8_t five_byte_buffer[5]; 
uint8_t two_byte_buffer[2]; 
//... 
ifstream my_file(/*...*/); 
my_file.read(&five_byte_buffer[0], 5); 
my_file.read(&two_byte_buffer[0], 2); 

Итак, что это ваш конкретный вопрос?

Edit 1: Чтение в цикле

while (my_file.read(&five_byte_buffer[0], 5)) 
{ 
    my_file.read(&two_byte_buffer[0], 5); 
    Process_Data(); 
} 
+0

Я не понял ваше сообщение, для чего предназначены эти два массива? И почему вы делаете 'my_file.read'? Я не программирую на C++, так что извините, если я сейчас глуп. –

+0

Ваше сообщение сказал, что вам нужно читать в 5 байт, а затем 2 байта. Буферы содержат данные, которые вы читаете. –

+0

'my_file.read' - это метод C++ для чтения необработанных данных из потока, в данном случае потока' my_file'. –