我有一个二进制逻辑数据,我希望以尽可能少的空间保存到文件中。当我从它显示的MATLAB工作区检查数据大小时,显示103 kb,但是当我使用fwrite ubit1保存它时,它会扩展到105 kb?我该怎么做才能在最小的空间内保存它?
答案 0 :(得分:0)
Matlab中的函数fwrite
添加了没有开销(或者您可能意味着元数据)。该功能为"低级"因为它来自给定的机器,它将提供与C
,C++
和更多语言中的等效低级函数类似的结果。
要访问磁盘,它们都将依赖于更低级别的功能,这些功能由磁盘的filesystem
和操作系统驱动。因此,在不同的磁盘,文件系统和操作系统之间,您可能会发现最终结果存在细微差别,但在给定系统(磁盘/ FS / OS)上,Matlab fwrite
与其他所有语言类似,并且没有& #34;开销"
现在达到数据大小与文件大小与磁盘大小的关系:
请考虑以下代码段:
nbits = 376 ;
A = true( nbits , 1 ) ;
fid = fopen( 'testsize.bin' , 'w' ) ;
fwrite( fid , A , 'ubit1' ) ;
fclose(fid) ;
这将创建一个376逻辑的数组,然后将其格式为ubit1
写入磁盘。
在我们查看文件之前,请注意,正如Horchler评论中提到的,在Memory Matlab中,仍然对每个逻辑(布尔值)使用一个完整的字节(8位)。
>> whos A
Name Size Bytes Class Attributes
A 376x1 376 logical
然而,这不是问题,因为当fwrite
将在磁盘上写入时,格式ubit1
将告诉它仅使用(单个)有效位,以便Horchler评论,该文件将恰好是内存中变量大小的1/8 ......
还是会?
如果我只是快速浏览一下我的文件浏览器,哎哟:
(这一切都在PC,Windows 8,NTFS文件系统上完成。)
1KB,naaaah,这只是因为这个东西的设计不是为了显示小于它的尺寸,它只是四舍五入。(unix / linux用户可能会得到更好的显示但是嘿我在Windows上我是必须处理它。)
为了获得更好的信息,我必须查询更多细节,所以一旦我访问文件的属性,我得到:
pfeeew。 47字节。这听起来是正确的。让我们看看376/8=47
,是的,这是完美的!
注意磁盘上的"大小"高达4KB。为什么你需要这么多空间来存储我糟糕的47个字节?这与"默认分配"有关。磁盘上文件系统的大小,以及fwrite
无法做任何事情的其中一个例子。它仅由OS /文件系统管理。
现在即使浪费了大量磁盘,我仍然设法获取信息,我的文件实际上只有47个字节。那么成功吗? ......还没有。
我在开始时几乎随机选择376位,但也因为它是8的完美倍数。现在让我们尝试运行与上面相同的代码,除非我们从以下开始:
nbits = 377 ;
代码运行正常。该文件在资源管理器中仍然显示为1KB但我们知道它是错误的,该属性现在显示:
377/8 = 47.125
,而不是48,所以它是"舍入"再次由探险家。 NO!
文件大小实际上是48字节(不是一点或更少)。 (但文件中的有用信息只占用47个字节和1个比特,最后7个比特未确定(或挂钩到' 0'可能但不确定)。
场景背后发生的事情是fwrite
聚合我的位以按8组写入,构建一个完整的字节,然后只在磁盘上写入完整的字节(有时甚至是更大的组)。它完成了幕后的所有操作,但它必须因为文件系统(是的,他再次)不会让他在磁盘上寻址个别位。文件系统期望至少一个字节(或更多)的包。因此,当到达要写入的最后一个位时,fwrite
必须在告诉文件系统将其写入磁盘之前用7个其他位填充该位。
我不是所有文件系统的专家,但我强烈怀疑很多人会允许你解决一个位,所以你应该期望的最小舍入总是至少一个字节...如果不是更多
fwrite
不会引入开销,也不会引入硬件和文件系统强制执行的开销(在这种情况下,任何其他函数都无法做得更好)。