我正在尝试写入不适合 8 位的文件二进制数据。据我了解,如果可以将其分组为 8、16、32,64 的预定义长度,则可以编写任意长度的二进制数据。有没有办法只将 9 位写入文件?还是两个 9 位的值?
我在 -+32768 范围内有一个值,在 +-256 范围内有 3 个值。节省大部分空间的方法是什么?
谢谢
不,我认为没有任何方法可以使用 C 的文件 I/O API:s 来表示存储少于 1char
的数据,通常为 8 位。
如果您使用的是 9 位系统,而CHAR_BIT
实际上是 9,那么这将是微不足道的。
如果您真正要问的是“我如何使用所需的精确位数存储一个范围有限的数字”,在一个可能更大的文件中,那么这当然是很有可能的。
这通常称为比特流,是优化用于某些信息的空间的好方法。编码/解码比特流格式要求您跟踪实际文件中当前输入/输出字节“消耗”了多少位。这有点复杂,但不是很难。
基本上,你需要:
s
,即您可以将字节放入的东西,例如FILE *
.i
,即一个无符号值,用于跟踪您发出了多少位。x
,可以放入位,每次递增i
。当i
达到时CHAR_BIT
,将其写入s
并重置i
为零。您也不能以 9 位存储 –256 到 +256 范围内的值。也就是513个值,9位只能区分512个值。
如果您的实际范围是 –32768 到 +32767 和 –256 到 +255,那么您可以使用位域将它们打包成一个结构:
struct MyStruct
{
int a : 16;
int b : 9;
int c : 9;
int d : 9;
};
像这样的对象仍然会被四舍五入到整数字节,所以上面的在典型系统上将有 6 个字节,因为它总共使用 43 位,而下一个 8 位字节的整数有 48 位。
您可以接受 43 位到 48 位的填充,或者在写入文件之前使用更复杂的代码进一步连接位。这需要额外的代码来将位组装成字节序列。很少值得付出努力,因为目前存储空间很便宜。
你可以应用 base64 的原理(只是扩大你的基地,而不是让它变小)。
每个值将被写入两个字节,并通过移位和或操作与最后一个/下一个字节组合。
我希望这个非常抽象的描述对您有所帮助。