为什么 Delphi 7 在 ASCII 码 14 后以追加模式打开时截断文件?
Why does Delphi 7 truncate file after ASCII code 14 when opening in Append mode?
我正在开发一些用 Delphi 7 编写的遗留软件,运行s 在 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.
我希望它创建包含 "before#14after#13#10"
的 a.txt
文件,然后不向其附加任何内容。但是,在 运行 这个程序在 Windows 之后,我在 a.txt
中看到了 before
,就像 Delphi 的 append
t运行分类文件。如果我不重新打开文件,它会按预期显示 before#14after#13#10
。
如果我在重新打开的文件中写了一些东西 (FooBar
),它会被追加,但好像文件已经被 t运行cated: beforeFooBar
.
对于 0 到 32 之间的任何其他字符,即使是 26(代表 EOF)也不会出现这种效果。
这是 Delphi 中的错误还是明确定义的行为? chr(14)
有什么特别之处?
感谢聊天中的一些朋友和评论中的 Sertac Akyuz:它看起来像是 Delphi 7 中的错误。
它应该对 EOF 符号 (ASCII 26) 进行特殊处理,引用自 here:
Note: If a Ctrl+Z (ASCII 26) is present in the last 128-byte block of the file, the current file position is set so that the next character added to the file overwrites the first Ctrl+Z in the block. In this way, text can be appended to a file that terminates with a Ctrl+Z.
有点 CP/M 向后兼容性,我想。
但是,Windows 的 TextOpen
的实现存在一个错误(请参阅 Delphi 7 安装中的 Source/Rtl/Sys/System.pas
大约 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
。不幸的是,由于某种原因编译 and it even appeared on Whosebug already。有一个名为 @@eof
的标签,仅此而已。
结果:我们没有 26 的特殊情况,而是 14 的特殊情况。确切原因尚未找到。
我正在开发一些用 Delphi 7 编写的遗留软件,运行s 在 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.
我希望它创建包含 "before#14after#13#10"
的 a.txt
文件,然后不向其附加任何内容。但是,在 运行 这个程序在 Windows 之后,我在 a.txt
中看到了 before
,就像 Delphi 的 append
t运行分类文件。如果我不重新打开文件,它会按预期显示 before#14after#13#10
。
如果我在重新打开的文件中写了一些东西 (FooBar
),它会被追加,但好像文件已经被 t运行cated: beforeFooBar
.
对于 0 到 32 之间的任何其他字符,即使是 26(代表 EOF)也不会出现这种效果。
这是 Delphi 中的错误还是明确定义的行为? chr(14)
有什么特别之处?
感谢聊天中的一些朋友和评论中的 Sertac Akyuz:它看起来像是 Delphi 7 中的错误。
它应该对 EOF 符号 (ASCII 26) 进行特殊处理,引用自 here:
Note: If a Ctrl+Z (ASCII 26) is present in the last 128-byte block of the file, the current file position is set so that the next character added to the file overwrites the first Ctrl+Z in the block. In this way, text can be appended to a file that terminates with a Ctrl+Z.
有点 CP/M 向后兼容性,我想。
但是,Windows 的 TextOpen
的实现存在一个错误(请参阅 Delphi 7 安装中的 Source/Rtl/Sys/System.pas
大约 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
。不幸的是,由于某种原因编译 and it even appeared on Whosebug already。有一个名为 @@eof
的标签,仅此而已。
结果:我们没有 26 的特殊情况,而是 14 的特殊情况。确切原因尚未找到。