Delphi - Sharing violation opening text file

12,065

Solution 1

Use the LoadFromStream method of TStringList, rather than LoadFromFile. You get to control the locking that way:

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;

That example is using the stream to load into a TStringList. If you only want to read pieces, you can do that. Just read from the stream.

Solution 2

It depends on how that other process opened the file... If it opened the file exclusively you are not going to succeed at all.

And TextFile is old hat, I think it will open in exclusive mode to be compatible with Old style DOS. You should use TFileStream or similar.

TStringList may also work, again depending on what the other process is doing. But if the file is being written (like a .log file) the fmShareDenyWrite won't work.

Solution 3

Maybe like this:

  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;

Solution 4

This will solve your problem instantly. Load the file using a TStringList. Just call:

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

I found that dealing with text files, it's best to use the TStringList. Otherwise I'd go for TFileStream and there you can specify your opening mode.

Solution 5

If I remember correctly, there is also a Textfilemode Variable that applies to text files only.

Share:
12,065

Related videos on Youtube

Simes
Author by

Simes

Updated on April 17, 2022

Comments

  • Simes
    Simes about 2 years

    I'm trying to open a text file for reading in a Delphi 7 app, but am getting I/O error 32 (sharing violation) because another application already has the file open. I've tried setting FileMode to "fmOpenRead or fmShareDenyNone" but now realise this doesn't apply to text files anyway.

    Is there a way of reading text files that are open by another application?

    var
      f: TextFile;
    begin
      FileMode := fmOpenRead or fmShareDenyNone;   // FileMode IS NOT APPLICABLE TO TEXT FILES!!
      AssignFile(f, FileName);
      Reset(f);
    
    • Remy Lebeau
      Remy Lebeau almost 12 years
      You can use TStreamReader to read lines from a TFileStream. It has a ReadLine() method, and does the buffering internally for you.
    • lkessler
      lkessler over 7 years
      @RemyLebeau - I tried using TStreamReader and it seems to give the access violation when the file is open by another application.
  • Lieven Keersmaekers
    Lieven Keersmaekers almost 15 years
    @MasterPeter, I believe the cullprit mghie is talking about is fmShareDenyWrite.fmShareDenyWrite "locks" a file so other processes can only read... A bit harsh though to downvote your answer because of it.
  • Simes
    Simes almost 15 years
    The problem with this is that it loads the whole file into memory. Some of the files can be big, and so I prefer to process them one line at a time.
  • Simes
    Simes almost 15 years
    That would be perfect, but it doesn't compile and can't find it in the help.
  • mghie
    mghie almost 15 years
    @Lieven: You're right on both accounts (I didn't downvote the answer either). @MasterPeter: Opening the file will fail if another process has it open for writing (non-exclusive). fmShareDenyNone is necessary in that case.
  • Peter Perháč
    Peter Perháč almost 15 years
    I just tried this and you're both right, it doesn't work if the other process has a fmOpenWrite access to it. However, I doubt Simes has this problem. (S)he just wants to read the file line by line and TextFile(s) doesn't seem to work for him/her. I haven't used TextFiles in all my life (I always used TStringLists whenever I needed to treat something as a text file), so I can't help any more than I already have attempted to :)
  • Ghigo
    Ghigo about 9 years
    This works and solve the issue. Only concern is about memory usage: whole file is loaded into memory. This could be an issue.