I use PowerShell command (get-item c:\temp\a.log).OpenRead()
to test what happen with the file.
After file is opened to read, if I issue (get-item c:\temp\a.log).OpenWrite()
, it will return the following error
Exception calling "OpenWrite" with "0" argument(s): "The process cannot access the file
'C:\temp\a.log' because it is being used by another process."
+ (get-item c:\temp\a.log).OpenWrite()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IOException
How can I release the OpenRead()
status?
Just to explain why you're seeing this behavior when you open a file with .OpenRead()
and then again with .OpenWrite()
, it's caused by sharing (or lack thereof), not locking. Sharing dictates what kind of access is allowed for other streams opened from the same file while the current stream is still open.
OpenRead
and OpenWrite
are convenience methods that wrap the FileStream
constructor; OpenRead
creates a read-only stream with read sharing allowed, and OpenWrite
creates a write-only stream with no sharing allowed. You may notice that there is another method called simply Open
with overloads that allow you to specify the access (second parameter) and sharing (third parameter) yourself. We can translate OpenRead
and OpenWrite
to Open
, thus...
$read = (get-item c:\temp\a.log).OpenRead()
# The following line throws an exception
$write = (get-item c:\temp\a.log).OpenWrite()
...becomes...
$read = (get-item c:\temp\a.log).Open('Open', 'Read', 'Read') # Same as .OpenRead()
# The following line throws an exception
$write = (get-item c:\temp\a.log).Open('OpenOrCreate', 'Write', 'None') # Same as .OpenWrite()
Either way you write it, the third line will fail to create a write-only stream because $read
will only allow other streams to read as well. One way to prevent this conflict is to close the first stream before opening the second:
$read = (get-item c:\temp\a.log).Open('Open', 'Read', 'Read') # Same as .OpenRead()
try
{
# Use $read...
}
finally
{
$read.Close()
}
# The following line succeeds
$write = (get-item c:\temp\a.log).Open('OpenOrCreate', 'Write', 'None') # Same as .OpenWrite()
try
{
# Use $write...
}
finally
{
$write.Close()
}
If you really do need a read-only and a write-only stream to be open on the same file simultaneously, you can always pass your own values to Open
to allow this:
$read = (get-item c:\temp\a.log).Open('Open', 'Read', 'ReadWrite')
# The following line succeeds
$write = (get-item c:\temp\a.log).Open('OpenOrCreate', 'Write', 'Read')
Note that the sharing goes both ways: $read
needs to include Write
in its sharing value so that $write
can be opened with Write
access, and $write
needs to include Read
in its sharing value because $read
is already open with Read
access.
In any case, it is always good practice to call Close()
on any Stream
when you are done using it.
I found a way to release the lock status
I just invoke another command:
$s = (get-item c:\temp\a.log).OpenRead()
, then use
$s.close()
The file is not locked anymore
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With