Home > OS >  TFileStream.Create - Open read write but allow others to readonly
TFileStream.Create - Open read write but allow others to readonly

Time:12-11

I am facing a situation where I need to open a file in readonly mode when the same exe might have already opened the same file (network share) in read/write mode. I must allow other users to at least read that file.

The EXE will be launched simultaneously by many different users on their machines pointing to the same shared file.

I am facing "Cannot open file '<file>'. The process cannot access the file because it is being used by another process" Error.

Is there any way that this could be solved?

Code to open in read/write mode

TFileStream.Create(<file>, fmOpenReadWrite or fmShareDenyNone);

Code to open in read only mode

TFileStream.Create(<file>, fmOpenRead);

CodePudding user response:

As per this table (do not look up the current version with messed up layout semantics) the second call must at least have the same sharing:

First call to CreateFile Valid second calls to CreateFile
GENERIC_READ | GENERIC_WRITE with FILE_SHARE_READ | FILE_SHARE_WRITE GENERIC_READ with FILE_SHARE_READ | FILE_SHARE_WRITE
GENERIC_WRITE with FILE_SHARE_READ | FILE_SHARE_WRITE
GENERIC_READ | GENERIC_WRITE with FILE_SHARE_READ | FILE_SHARE_WRITE

Which means: the second call must at least share the same. So you must call

TFileStream.Create('filename', fmOpenRead or fmShareDenyNone);

...if you want to succeed.

Why does this make sense? Because when a third caller wants to open the file the OS does not maintain a chronological list of who opened it first and second, hence there is no "the first opener is more right than the second opener". If the second caller would reduce it from "share all" down to "share read" then why should a third caller adhere to that and not to the first caller's "share all" mode?

CodePudding user response:

You describe a situation where several users might simultaneously access a file. I guess, that it can not be predicted who is the first to attempt to access the file. I also understood that all want to write to the file when they access it, or if they don't immediately get write access, they will try again later.

Attempt

TFileStream.Create(<file>, fmOpenReadWrite or fmShareDenyNone);

If it succeeds, write to the file, and close it. Task done.

If the above fails, and you still want to read the file, try

TFileStream.Create(<file>, fmOpenRead or fmShareDenyNone);

If it succeeds, read the file and close it. Retry later if you still need to write to the file.

  • Related