Почему Delphi 7 усекает файл после кода ASCII 14 при открытии в режиме добавления? - PullRequest
6 голосов
/ 02 мая 2020

Я работаю над устаревшим программным обеспечением, написанным на 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 вместо a.txt я вижу before, как если бы Delphi s append усекает файл. Если я не открываю файл заново, он показывает before#14after#13#10, как и ожидалось.

Если я что-то записываю (FooBar) в повторно открытый файл, он добавляется, но, как будто файл уже был усечено: beforeFooBar.

Этот эффект не возникает с любым другим символом от 0 до 32, даже с 26 (что означает EOF).

Это ошибка в Delphi или четко определенное поведение? Что такого особенного в chr(14)?

1 Ответ

5 голосов
/ 03 мая 2020

Спасибо некоторым друзьям из чата и Серте c Акьюзу из комментариев: похоже, что это ошибка в Delphi 7.

Предполагается, что он имеет специальную обработку символа EOF (ASCII 26) в кавычках от здесь :

Примечание. Если Ctrl + Z (ASCII 26) присутствует в последнем 128-байтовом блоке файла, устанавливается текущая позиция файла так что следующий символ, добавленный в файл, перезаписывает первые Ctrl + Z в блоке. Таким образом, текст может быть добавлен в файл, который заканчивается Ctrl + Z.

Вид CP / M Обратная совместимость, я полагаю.

Однако в реализации 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. Точная причина еще не найдена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...