Delphi - нарушение прав доступа при открытии текстового файла - PullRequest
6 голосов
/ 26 апреля 2009

Я пытаюсь открыть текстовый файл для чтения в приложении Delphi 7, но получаю ошибку ввода-вывода 32 (нарушение общего доступа), потому что другое приложение уже имеет открытый файл Я попытался установить FileMode на «fmOpenRead или fmShareDenyNone», но теперь понимаю, что это не относится к текстовым файлам.

Есть ли способ чтения текстовых файлов, открытых другим приложением?

var
  f: TextFile;
begin
  FileMode := fmOpenRead or fmShareDenyNone;   // FileMode IS NOT APPLICABLE TO TEXT FILES!!
  AssignFile(f, FileName);
  Reset(f);

Ответы [ 5 ]

12 голосов
/ 12 мая 2010

Используйте LoadFromStream метод TStringList вместо LoadFromFile. Вы можете управлять блокировкой таким образом:

var
    slFile: TStrings;
    stream: TStream;
begin
   slFile := TStringList.Create;
   try
      stream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone);
      try 
         slFile.LoadFromStream(stream);
      finally
         stream.Free;
      end;

      //Use the stringlist
   finally
      slFile.Free;
   end;
end;

Этот пример использует поток для загрузки в TStringList. Если вы хотите читать только фрагменты, вы можете это сделать. Просто прочитайте из потока.

3 голосов
/ 26 апреля 2009

Это зависит от того, как другой процесс открыл файл ... Если он открыл файл исключительно, у вас ничего не получится.

А TextFile - это старая шляпа, я думаю, она откроется в эксклюзивном режиме, чтобы быть совместимой с DOS старого стиля. Вы должны использовать TFileStream или аналогичный.

TStringList также может работать, опять же, в зависимости от того, что делает другой процесс. Но если файл записывается (например, файл .log), fmShareDenyWrite не будет работать.

1 голос
/ 28 апреля 2009

Может быть так:

  vFileList := TStringList.Create;
  try
    vFileStream := TFileStream.Create('myfile.txt', fmOpenRead or fmShareDenyNone);
    try
      vFileList.LoadFromStream(vFileStream);
    finally
      vFileStream.Free;
    end;
    // Use vFileList
  finally
    vFileList.Free;
  end;
1 голос
/ 26 апреля 2009

Если я правильно помню, существует также переменная Textfilemode, которая применяется только к текстовым файлам.

1 голос
/ 26 апреля 2009

Это решит вашу проблему мгновенно. Загрузите файл, используя TStringList. Просто позвоните:

...
var sl: TStringList;
begin
  sl := TStringList.create();
  try
    sl.loadFromFile(Filename);
    ...do your stuff here...
  finally
    freeAndNil(sl);
  end;
end;

Я обнаружил, что при работе с текстовыми файлами лучше всего использовать TStringList. В противном случае я бы пошел на TFileStream и там вы можете указать свой режим открытия.

...