tags:

views:

47

answers:

2

Hi,

Hopefully more of a "What am I doing wrong?" than "How do I?" but there you go...

Basically, I'm trying to get a program to behave in the following way:

  • First instance of the program opens up on PC1, opens a file for Read/Write access and then acts as the master program, doing a bunch of work on some other files I don't want a whole bunch of users accessing at once.

  • Second instance of the program starts up, tries to open the file for Read/Write access, fails, enters Slave mode, opens the file for Read access, and periodically reads the status of the other files from this file.

That's the plan, anyway. If anyone can suggest a better way to handle the master/slave decision-making, I'm open to suggestions.

Anyway, as a lead-up to implementation, I've got two instances of Visual Studio open. One is running a project called "GetFile", the other is running a project called "TryGetFile".

"GetFile" has a Private myStream As IO.FileStream object and opens the test file using this line:

myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.OpenOrCreate,
                            IO.FileAccess.ReadWrite, IO.FileShare.ReadWrite)

This works fine and, as far as I can tell, should leave this file accessible for further Read/Write access by any other process, which is fine for this stage of the testing.

"TryGetFile" also has a Private myStream As IO.FileStream object, but it attempts the following open code:

myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.Open, 
                            IO.FileAccess.Read, IO.FileShare.Read)

This doesn't work at all. I get an IOException, which reports that test.txt is opened by another process and I'm not allowed to play with it.

Basically, I don't see what the problem is; I don't think "TryGetFile" is asking for any file access which "GetFile" forbids it from having. As far as I can see, "GetFile" shouldn't be forbidding any kind of access at all...

What am I screwing up, here?

EDIT: Hmm...

Okay, Henk and Richard have answered the original question, as posed, pointing out that the problem is that "TryGetFile" is attempting to narrow the file sharing permission to Read, where "GetFile" already allows ReadWrite access. Altering "TryGetFile" to also allow ReadWrite sharing lets the code run.

Unfortunately altering the code as per their suggestions, so that both "GetFile" and "TryGetFile" permit IO.FileShare.Read sharing:

'GetFile
myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.Open,
                            IO.FileAccess.ReadWrite, IO.FileShare.Read)

'TryGetFile
myStream = IO.File.Open("\\[network path]\test.txt", IO.FileMode.Open,
                            IO.FileAccess.Read, IO.FileShare.Read)

causes TryGetFile to throw an IOException again.

What's wrong, here?

+1  A: 

You should be able to do it this way, in all instances:

  1. Open with FileAccess.ReadWrite and FileShare.Read
  2. If #1 has failed open with FileAccess.Read and FileShare.ReadWrite

The first will only work if no-one else has a write lock (and adds a write lock), but will allow other readers (which is then used in 2). But, as it turns out those subsequent readers must also allow others to write.


Updated with that last note after testing in PowerShell ($name includes the absolute path of the file, to avoid the effect of PowerShell not directly surfacing the process's underlying current directory):

First process:

$file = [io.file]::Open($name, [io.filemode]::Open, [io.fileaccess]::ReadWrite, [io.fileshare]::Read)

Second process:

$file = [io.file]::Open($name, [io.filemode]::Open, [io.fileaccess]::Read, [io.fileshare]::readwrite)

And I see, in Process Explorer that the file is open in both processes.

Richard
If 1 is opening for ReadWrite _permission_, then it appears that 2 is unable to then request Read permission, regardless of the sharing setting. This seems illogical to me. Am I doing something else wrong?
Frosty840
@Frosty840: not quite, #1 is opening the file for read/write, but only locking for writer. I.e. other opens for read-only are OK.
Richard
Yeah, I thought so too, but trying to do so throws an exception.
Frosty840
@Frosty840: Slight correction (having now tested in PowerShell), #2 has to allow other writers (which initially seems odd, but makes sense considering there is already another writer). Will update.
Richard
A: 

A FileShare value specifying the type of access other threads have to the file.

So you need ReadWrite for both TryGetFile and GetFile.

pinichi