如何从文件中读取不同大小的位值?

问题描述:

我从一个文本文件中读取一串二进制位的值,因为我使用fwrite存储它们。问题是文件中的第一个值是5个字节,接下来的4800个值是2个字节。所以当我试图循环读取文件并读取值时,它会给我错误的结果,因为我的程序不知道第一次需要5个字节,剩下的4800次需要2个字节。如何从文件中读取不同大小的位值?

这里是我如何骑自行车通过文件:

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?你可以让我知道我可以改变什么,使我的计划完成我所需要的。

编辑:

这是我如何写入文件。

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

你不能。流是字节,几乎总是八位字节(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; 
    } 

您需要决定如何知道流何时终止。因为你会用fgetc()读取的EOF损坏最后几位。

+0

对不起,但我是一个完整的C++ noob,你能解释一下你的意思吗?我还有办法完成我所需要的吗?像是没有办法,我可以区分'time_t'值和'unsigned_short'值? –

我没有看到这个问题:

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); 

那么,什么是你的具体问题?

编辑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'流。 –