我正在编写压缩程序,需要使用c ++将位数据写入二进制文件。如果有人可以在写声明或建议网站上提出建议,我将非常感激。
如果这是一个简单或令人困惑的问题,我很难道歉,我很难在网上找到答案。
答案 0 :(得分:3)
将这些位收集到整个字节中,例如unsigned char或std :: bitset(其中bitset size是CHAR_BIT的倍数),然后一次写入整个字节。计算机“处理位”,但可用的抽象 - 特别是对于IO - 是作为程序员处理单个字节的。按位操作可用于切换特定位,但您总是处理字节大小的对象。
在输出结束时,如果没有整个字节,则需要决定应该如何存储。 iostream和stdio都可以分别使用ostream :: write和fwrite写入未格式化的数据。
而不是单个char或bitset< 8> (8是CHAR_BIT的最常见值),您可以考虑使用更大的块大小,例如4-32或更多的数组,字符或等效大小的位集。
答案 1 :(得分:2)
对于二进制文件,我发现最有用的技巧是将所有二进制文件作为单个数组存储在内存中,然后将其全部移动到硬盘驱动器上。一次做一点,或一次做一个字节,或一次做一个无符号长,并不像将所有数据存储在一个数组中并使用一个“fwrite()”实例将它存储到硬盘。
size_t fwrite(const void * ptr,size_t size,size_t count,FILE * stream);
参考:http://www.cplusplus.com/reference/clibrary/cstdio/fwrite/
英文:
fwrite([存储数据的数组],[数组OBJECT的字节大小。对于无符号字符 - > 1,对于无符号长整数 - > 8],[数组中的实例数],[文件* ])
请务必检查您的退货以确认成功!
此外,可以使对象类型尽可能大的参数是最快的方法([unsigned long long]> [char])。虽然我不熟悉“fwrite()”背后的编码,但我觉得从代码中使用的自然对象转换为[unsigned long long]的时间与写入相比将花费更多时间而不是“fwrite()” “用你所拥有的东西来弥补。
当我学习Huffman Coding时,我花了几个小时才意识到[char]和[unsigned char]之间存在差异。请注意,此方法应始终使用无符号变量来存储纯二进制文件。
答案 2 :(得分:1)
通过下面的类,你可以逐位写入和读取
class bitChar{
public:
unsigned char* c;
int shift_count;
string BITS;
bitChar()
{
shift_count = 0;
c = (unsigned char*)calloc(1, sizeof(char));
}
string readByBits(ifstream& inf)
{
string s ="";
char buffer[1];
while (inf.read (buffer, 1))
{
s += getBits(*buffer);
}
return s;
}
void setBITS(string X)
{
BITS = X;
}
int insertBits(ofstream& outf)
{
int total = 0;
while(BITS.length())
{
if(BITS[0] == '1')
*c |= 1;
*c <<= 1;
++shift_count;
++total;
BITS.erase(0, 1);
if(shift_count == 7 )
{
if(BITS.size()>0)
{
if(BITS[0] == '1')
*c |= 1;
++total;
BITS.erase(0, 1);
}
writeBits(outf);
shift_count = 0;
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
}
if(shift_count > 0)
{
*c <<= (7 - shift_count);
writeBits(outf);
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
outf.close();
return total;
}
string getBits(unsigned char X)
{
stringstream itoa;
for(unsigned s = 7; s > 0 ; s--)
{
itoa << ((X >> s) & 1);
}
itoa << (X&1) ;
return itoa.str();
}
void writeBits(ofstream& outf)
{
outf << *c;
}
~bitChar()
{
if(c)
free(c);
}
};
代表example
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
ofstream outf("Sample.dat");
ifstream inf("Sample.dat");
string enCoded = "101000001010101010";
//write to file
cout << enCoded << endl ; //print 101000001010101010
bitChar bchar;
bchar.setBITS(enCoded);
bchar.insertBits(outf);
//read from file
string decoded =bchar.readByBits(inf);
cout << decoded << endl ; //print 101000001010101010000000
return 0;
}