为什么Delphi 7在Append模式下打开时,会在ASCII码14之后截断文件?

问题描述 投票:3回答:1

我正在处理一些用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上运行这个程序后,我看到了以下内容 beforea.txt 而不是像Delphi的 append 截断文件。如果我不重新打开文件,它就会显示出 before#14after#13#10 如期而至。

如果我写一些(FooBar)在重新打开的文件中,它被追加了,但好像文件已经被截断了。beforeFooBar.

这种效果不会发生在0和32之间的任何其他字符上,即使是26(代表EOF)。

这是Delphi中的一个bug还是一个定义良好的行为?有什么特别之处呢?chr(14)?

delphi ascii
1个回答
5
投票

感谢聊天中的一些朋友和评论中的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的特例。具体原因还没有找到。

© www.soinside.com 2019 - 2024. All rights reserved.