views:

866

answers:

4

Hi!

Yes I want to read a simple a logfile into a TStringList and that is easy done with LoadFromFile. But the problem is that the file can be already opened by another program at the same time so an exception may appear. I have tried to use:

FileMode := fmShareCompat;

But it won't work.

I have also tried to use:

fFilePath := fPathList[PathIndex] + '\' + FileData.Name;
AssignFile(vFile, fFilePath);
Reset(vFile, 1);  // Recordsize = 1

SetLength(vFileString, FileData.Size);
BlockRead(vFile, vFileString, FileData.Size);   
vCurrentFile.Text := vFileString;

It raise an EInOutError with message I/O error 998.

Any suggestion ?

+11  A: 

Try LoadFromStream and do something like:

fileStream := TFileStream.Create(aFileName, fmShareDenyNone);
myTStringList.LoadFromStream(fileStream);
fileStream.Destroy();
Drejc
Do not call Destroy directly in an application. Instead, call Free, which checks that the TFileStream reference is not nil and only then calls Destroy.
inzKulozik
You are rigth it should be Free not Destroy ...
Drejc
Correction: Destroy is quite acceptable in the above example. `MyObject.Free` is equivalent to `if MyObject <> nil then MyObject.Destroy`. The reason you use `Free` is to provide a check whether the reference has been assigned. In the above example you can safely guarantee that by reaching line 3 that `fileStream` references an object that was correctly created. What is missing however (an much more of an issue) is the `try..finally` statement. Also, depending on the scope of the `fileStream` variable, it may be advisable to clear it: `finally fileStream.Destroy; fileStream := nil; end;`
Craig Young
before a discussion about Free or Destroy starts you may want to read this: http://blogs.embarcadero.com/abauer
Joe Meyer
I was always somehow confused why there are two methods available, and honestly I almost in every case use Destroy over Free. This is because it will throw an exception in cases I have not assigned the object and so bugs are faster detected.
Drejc
+1  A: 

Also, try..except and try..finally are good friends at these times. Encapsulate your file reading code in these types of blocks and tell the user about the problem that arises.

Niklas Winde
Yes I know. But I want to search many log-files in a directory. If I have a try except for every file load maybe it slow down the execution. It is already rather slow.../Roland
Roland Bengtsson
You actually want a try / finally for every file. Unless you are reading a lot of really small files I don't see it impacting performance significantly. If it does, then you may want to consider a different mechanism all together.
Jim McKeeth
@Niklas: NO! NO! NO! and NO again! Do not abuse try..except! Hiding errors with try..except leads to a huge amount of insidious bugs in the long run.
Craig Young
@Craig Young: Did you miss the part of my answer that says "...and tell the user about the problem that arises"? That is not hiding errors, that is handling them gracefully in my book.
Niklas Winde
A: 

Thanks a lot! This was the fastest answer ever in a forum.

Now I can continue with other parts of my application.

Sinceraly Roland

Roland Bengtsson
If Drejc's answer's the one you liked, you should really accept his answer, and thus up his reputation.
Frank Shearar
+4  A: 

fmShareCompat should probably be marked as deprecated. You want fmShareDenyNone (as Drejc said)

fmShareCompat comes from 16 DOS days I believe. On Windows, it is treated the same as fmShareExclusive. When Linux was supported it was treated the same as fmShareDenyNone.

Jim McKeeth