Delphi - Sharing violation opening text file
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.
Related videos on Youtube
Simes
Updated on April 17, 2022Comments
-
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 almost 12 yearsYou can use
TStreamReader
to read lines from aTFileStream
. It has aReadLine()
method, and does the buffering internally for you. -
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 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 almost 15 yearsThe 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 almost 15 yearsThat would be perfect, but it doesn't compile and can't find it in the help.
-
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áč almost 15 yearsI 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 about 9 yearsThis works and solve the issue. Only concern is about memory usage: whole file is loaded into memory. This could be an issue.