我正在处理一些用Delphi 7编写的遗留软件,该软件在Windows上运行。我将问题简化为以下程序。
var f: text;
begin
assign(f, 'a.txt');
rewrite(f);
writeln(f, 'before' + chr(14) + 'after');
close(f);
assign(f, 'a.txt');
append(f);
close(f);
end.
我希望它能创建 a.txt
载有 "before#14after#13#10"
然后不附加任何内容。然而,当我在Windows上运行这个程序后,我看到了以下内容 before
在 a.txt
而不是像Delphi的 append
截断文件。如果我不重新打开文件,它就会显示出 before#14after#13#10
如期而至。
如果我写一些(FooBar
)在重新打开的文件中,它被追加了,但好像文件已经被截断了。beforeFooBar
.
这种效果不会发生在0和32之间的任何其他字符上,即使是26(代表EOF)。
这是Delphi中的一个bug还是一个定义良好的行为?有什么特别之处呢?chr(14)
?
感谢聊天中的一些朋友和评论中的Sertac Akyuz:这看起来像是Delphi 7中的一个bug。
它应该是对EOF符号(ASCII 26)有特殊的处理,引用自 此处:
注:如果文件的最后128字节块中有Ctrl+Z(ASCII 26),则设置当前文件位置,以便添加到文件中的下一个字符覆盖该块中的第一个Ctrl+Z。这样一来,就可以将文本追加到以Ctrl+Z结束的文件中。
样的 CPM 向后兼容,我想。
然而,在实现 TextOpen
的Windows(见 Source/Rtl/Sys/System.pas
从您的 Delphi 7 安装中的第 4282 行左右)。)
@@loop:
CMP EAX,EDX
JAE @@success
// if (f.Buffer[i] == eof)
CMP byte ptr [ESI].TTextRec.Buffer[EAX],eof
JE @@truncate
INC EAX
JMP @@loop
这里说 eof
而不是 cEof
. 不幸的是,由于某些原因,这编译 它甚至已经出现在StackOverflow上。. 有一个标签叫 @@eof
就这样。
后果:我们没有26的特例,而是14的特例。具体原因还没有找到。