views:

105

answers:

2

I'm using a TFileSteam to open a log file. I would like to be able to read through this log file from other processes. I thought the fmShareDenyWrite mode would allow this.

However if I try to open the file from other processes, I get an error. For example, if I try and type the file from the command line, I get "the process can not access the file because it is being used by another process".

Here is the file initialization code:

if FileExists(AutoLogFileName) then
   _ActivityLogStream := TFileStream.Create(AutoLogFileName, 
          fmOpenReadWrite or fmShareDenyWrite)
else
   _ActivityLogStream := TFileStream.Create(AutoLogFileName, 
          fmCreate or fmShareDenyWrite);

NOTE: I am using Delphi version 6.

+2  A: 

mfCreate mode does not behave/work correctly with any share attribute. To work around, you must create file handle yourself and pass it to the constructor

Cheer

APZ28
Could you give me a code sample?
Aheho
+5  A: 

Don't know whether this was already a bug in D6, but that is a distinct possibility. There is a QC report on this reported against D2007: QC 65767: http://qc.embarcadero.com/wc/qcmain.aspx?d=65767. This report is now closed, as it was resolved in D2010 (14.0.3467.22472 to be exact).

Update (prompted by Gabr's comment):

You can create your own TFileStream descendant that does honor the mode. Just override the Create(const AFileName: string; Mode: Word; Rights: Cardinal) constructor (there are two overloaded constructors) and handle the mode parameter yourself. Copy the code from the original constructor and change the

  if Mode = fmCreate then
  begin
    inherited Create(FileCreate(AFileName, Rights));

to

  if (Mode and fmCreate = fmCreate) then
  begin
    myMode := Mode and $FF;
    if myMode = $FF then
      myMode := fmShareExclusive;
    inherited Create(FileCreate(AFileName, myMode, Rights));

where myMode is a local var of type Word.

Marjan Venema
That QC entry also provides the solution.
gabr