【发布时间】:2011-02-21 13:56:03
【问题描述】:
我的任务是为Unitech HT630 编写一个数据收集程序,它运行一个专有的 DOS 操作系统,可以运行为 16 位 MS DOS 编译的可执行文件,但有一些限制。我正在使用 Digital Mars C/C++ 编译器,它目前运行良好。
应用程序要求之一是数据文件必须是人类可读的纯文本,这意味着文件可以导入 Excel 或用记事本打开。我使用的可变长度记录格式很像 CSV,我已经使用 C 标准库文件 I/O 函数成功实现了该格式。
保存记录时,我必须计算更新的记录是否大于或小于数据文件中当前记录的版本。如果更大,我首先将当前记录之后的所有记录向前移动,按保存更新记录之前计算的大小差异。操作系统会自动扩展 EOF 以容纳额外的数据。如果更小,我将所有记录向后移动我计算的偏移量。这很好用,但是我发现无法修改 EOF 标记或文件大小以忽略最后一条记录结束后的数据。
大多数情况下,记录的大小会增加,因为数据收集程序会在保存记录时用数据填充一些空白字段。仅当对现有条目进行更正时,记录的大小才会缩小,或者如果记录中的描述性数据比程序在内存中读取的数据长,则在正常记录保存时会缩小。
在记录缩小的情况下,在文件中的最后一条记录之后,我留下了轮班前的所有数据。在“缩小记录保存”之后,我一直在文件中写入一个 EOF 分隔符,以指示我的记录的末尾在哪里并填充剩余数据的空间,但是在“增长记录保存”之前我不再有一个干净的文件在空间填充区域上扩展文件的大小。 unistd.h 中的 truncate() 函数不起作用(我现在认为这仅适用于 *nix 风格?)。
我见过的一个建议的解决方案是创建第二个文件并将您希望保存的所有数据写入该文件,然后删除原始文件。由于我只有 4MB 的磁盘空间可供使用,因此如果文件大小小于 2MB 减去我的程序可执行文件和配置文件的大小,则此方法有效,否则会失败。很有可能当它投入生产时,用户最终会得到一个超过 2MB 的文件。
我查看了Ralph Brown's Interrupt List 和IBM PC Assembly Language and Programming 中的中断引用,我似乎找不到任何可以更新文件大小或类似内容的内容。
在 DOS 中是否可以在不创建第二个文件的情况下减小文件大小?
【问题讨论】:
-
FAT FS 是否存在于 Flash 上?这可能不是问题(取决于使用情况),但以这种方式对文件进行碎片整理不会很好地适应闪存有限的擦除/写入寿命。
-
@nategoose - 该设备有一个 RAM 驱动器分区和一个 256k 闪存分区,我目前正在严格使用 RAM 驱动器。 flash分区仅用于存储程序,不用于存储数据。
-
某些操作系统(包括 DOS)可能会将文件填充到最接近的有效扇区大小。从偶数扇区边界开始的文件比那些没有的文件更容易和更快地检索。
标签: c file-io dos truncate fat