Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Read Text file and allow to be opened for writing

Status
Not open for further replies.

HZ1

Programmer
Nov 28, 2006
4
US
I would like to scan a log file in read only mode w no locking. I have tried with FileStream, AssignFile and even CopyFile. My issue is that there is a process running that needs to write to the file which may be during the time I am reading. I have the file open in fmOpenRead or fmShareDenynone and have no issues with opening. However, the app that needs to write to the file errors out w 'Cannot open log file C:\XXX.log' -- it's trying to open the same file in fmOpenReadWrite or fmShareCompat.. any ideas? (I can't change the code for the app that's writing to the log)

Sample code:

I'm coding in Delphi and using the Windows and SysUtils units:

try
fFileStreamOne := TFileStream.Create( fFileName, fmOpenRead or fmShareDenyNone );
fFileStreamTwo := TFileStream.Create( fFileName, fmOpenReadWrite or fmShareCompat );
finally
fFileStreamOne.Destroy;
// fFileStreamTwo.Destroy; -- exception
end;

(if both would be open for fmRead or fmShareDenyNone there are no issues)

Other failed solutions:

try
FileHandle := FileOpen(fFileName, fmOpenRead or fmShareDenyNone);
fFileStreamTwo := TFileStream.Create( fFileName, fmOpenReadWrite or fmShareCompat );
finally
FileClose (FileHandle);
// fFileStreamTwo.Destroy;
end;

-----------------------

try
AssignFile(F, fFileName); { File selected in dialog box }
FileMode := 0; {Set file access to read only }
with TTextRec(f) do begin

// else we try generic_read, file_share_read or file_share_write

handle:=FileOpen(fFileName,fmShareDenyNone);
if dword(handle)=invalid_handle_value then begin
raise EInOutError.CreateResFmt(@SInOutError, [GetLastError]);
end;
mode:=fmInput;
BufPos:=0;
BufEnd:=0;
end;
fFileStreamTwo := TFileStream.Create( fFileName, fmOpenReadWrite or fmShareCompat );
finally
CloseFile(F);
// fFileStreamTwo.Destroy; // exception
end;

-------------------------------------------
try
AssignFile(F, fFileName); { File selected in dialog box }
FileMode := 0; {Set file access to read only }
Reset(F);
Readln(F, S); { Read the first line out of the file }
Readln(F, S); { Read the second line out of the file }
// try open for stream writing:
fFileStreamTwo := TFileStream.Create( fFileName, fmOpenReadWrite or fmShareCompat );
finally
CloseFile(F);
// fFileStreamTwo.Destroy; // (exception)
end;
 
The way I read the docs I believe you want to use
fmShareDenyNone. Allows full access for others.
 
the reading is done w fmOpenRead or fmShareDenyNone the writing is done w fmOpenReadWrite or fmShareCompat.. even if writing is doen w fmOpenReadWrite or fmShareDenyNone still can't open the file for writing while it's being read or even while it's being copied...

I need a solution which opens the file in readonly mode or copies the file without holding any locks on the file and allowing fmOpenReadWrite. I read that for text files the modes don't apply which can be the issue here..
 
is F a text file type? If so you need to be changing the mode variable in the text file record.

as in
Code:
TTextRec(F).Mode := FmInput;

 
if I'm reading your code correctly, you don't have an issue with the file you are reading, it's your output file. Perhaps the TFileStream you're creating for it is not being created?

It's good practice to call Free instead of Destroy in your applications, this will avoid exceptions if the object being destroyed was never created.
 
wait... you're opening the same file twice in both read and readwrite mode? And another application somewhere also has the file open in write mode?

How do you know that the changes you're writing aren't being clobbered by the other application, unless you use some sort of locking?
 
It's for a logsearch function. I open the log in readonly mode to scan for a search text. While I have it open, the application that uses it as a log should be able to write to it. The app opens the file in fmOpenReadWrite or fmShareCompat... I have updated to use FREE but still it's an issue.. What happens is, the application logs that it can't open the file.. meaning that even though I am opening it in the mode: fmOpenRead or fmShareDenyNone I am still holding a lock on it...
 
Perhaps the application is trying to open the file with fmShareDenyAll...
 
the issue is the code in the app:
It opens the log in fmOpenReadWrite and fmShareCompat mode. fmShareCompat mode and fmShareExclusive work the same way.
They both evaluate to 0: (fmShareCompat = ShareMode[0], fmShareExclusive = ShareMode[1])
(SysUtils.FileOpen)
ShareMode: array[0..4] of LongWord = (
0,
0,
FILE_SHARE_READ,
FILE_SHARE_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE);
fmShareExclusive cannot open the file if it’s open for read or write. Therefore, every time the log is opened for searching and the App tries to write to it, it cannot.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top