views:

1134

answers:

4

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);
A: 

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.

Peter Perháč
not helpful? Simes, have you tried this?
Peter Perháč
LoadFromFile() uses (at least in Delphi 5 and 2007 it does) "fmOpenRead or fmShareDenyWrite" for the mode. This is definitely not what the OP is wanting.
mghie
??? This is exactly what Simes wants, though. He just wants to READ the file without caring about other processes using it. That was exactly his question.
Peter Perháč
@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.
Lieven
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
@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.
mghie
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 :)
Peter Perháč
+1  A: 

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

dummzeuch
That would be perfect, but it doesn't compile and can't find it in the help.
Simes
A: 

Maybe like this:

  vFileList := TStringList.Create;

  try
    vFileStream := TFileStream.Create('myfile.txt', fmShareDenyNone);
    vFileList.LoadFromStream(vFileStream);
    vFileStream.Destroy;

    // Use vFileList
  finally
    vFileList.Free;
  end;
Roland Bengtsson
A: 

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;
Ian Boyd