我的任务是编写一个Unitech HT630的数据收集程序,它运行一个专有的DOS操作系统,可以运行为16位MS DOS编译的可执行文件,但有一些限制。我使用的是Digital Mars C / C ++编译器,到目前为止运行良好。
其中一个应用程序要求是数据文件必须是人类可读的纯文本,这意味着该文件可以导入Excel或由记事本打开。我使用的是一种可变长度的记录格式,就像我使用C标准库文件I / O函数成功实现的CSV一样。
保存记录时,我必须计算更新的记录是大于还是小于数据文件中当前记录的版本。如果更大,我首先将当前记录之后的所有记录立即转移所计算的大小差异,然后再保存更新的记录。操作系统自动扩展EOF以容纳额外数据。如果更小,我将所有记录向后移动我计算的偏移量。这很好用,但我发现无法修改EOF标记或文件大小以在最后一条记录结束后忽略数据。
大多数时间记录的大小会增加,因为数据收集程序会在保存记录时用数据填充一些空字段。只有当记录中的描述性数据长于程序在内存中读取的内容时,记录才会在对现有条目进行更正时缩小,或者在正常记录上进行缩小。
在收缩记录的情况下,在文件中的最后一条记录之后,我留下了在班次之前坐在那里的任何数据。在“缩小记录保存”之后,我一直在向文件中写入EOF分隔符,以指示记录结束的位置并填充剩余数据,但是在“增长记录保存”之前我不再有一个干净的文件在空间填充区域上扩展文件的大小。 truncate()
中的unistd.h
函数不起作用(我现在认为这仅适用于* nix风格?)。
我见过的一个提议的解决方案涉及创建第二个文件并将您要保存的所有数据写入那个文件,然后删除原始文件。由于我只有4MB的磁盘空间可供使用,如果文件大小小于2MB减去程序可执行文件和配置文件的大小,则可以使用,但否则会失败。很可能在用于生产时,用户最终会得到一个超过2MB的文件。
我查看了Ralph Brown's Interrupt List和IBM PC Assembly Language and Programming中的中断参考,我似乎无法找到更新文件大小或类似内容的任何内容。
减少文件大小而不在DOS中创建第二个文件吗?
答案 0 :(得分:4)
要在DOS中减小文件的大小,可以使用int 21 (ax=4200h, bx=handle, cx:dx=offset)
进行截断,并使用零长度调用write:int 21 (ax=4000h, bx=handle, cx=0
(意味着截断))
答案 1 :(得分:0)
作为在调整记录大小时移动记录的替代方法,您可以使用“填充”字段完成每个记录,将其填充到标准大小(例如,使用空格或类似)。