如何从锁定状态释放(get-item c:\ temp \ a.log).OpenRead()?

时间:2017-06-14 02:32:02

标签: powershell

我使用PowerShell命令(get-item c:\temp\a.log).OpenRead()来测试文件会发生什么。

打开文件阅读后,如果我发出(get-item c:\temp\a.log).OpenWrite(),它将返回以下错误

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

如何发布OpenRead()状态?

3 个答案:

答案 0 :(得分:2)

我找到了释放锁定状态的方法

我只是调用另一个命令:

$s = (get-item c:\temp\a.log).OpenRead()  

,然后使用

$s.close()

该文件不再被锁定

答案 1 :(得分:1)

我发现之前的帖子很有效,因为变量$ s就是我之前调用的$ s =(get-item c:\ temp \ a.log).OpenRead()。

所以$ s只是需要关闭的对象。

我尝试以下测试以使其更清晰。

案例1:

$a = (get-item a.txt).OpenRead()  #the a.txt is locked
$a.Close() #a.txt is unlocked

情况2:

$a = (get-item a.txt).OpenRead()  #the a.txt is locked
$b = (get-item a.txt).OpenRead()
$a.Close() #a.txt is locked
$b.close() #a.txt is unlocked

情形3:

 $a = (get-item a.txt).OpenRead()  #the a.txt is locked
 $a = "bbb"  #the a.txt is locked for a while, finally it will unlock

对于case3,似乎系统将处理悬空对象,然后释放锁定状态。

答案 2 :(得分:1)

只是解释为什么当您使用.OpenRead()打开文件然后再使用.OpenWrite()打开文件时会出现此行为,这是由 sharing 引起的(或缺乏),而不是locking。共享指示当前流仍处于打开状态时,从同一文件打开的其他流允许哪种访问。

OpenReadOpenWrite是包含FileStream constructor的便捷方法; OpenRead创建一个允许读取共享的只读流,OpenWrite创建一个只允许 no 共享的只写流。您可能会注意到另一种简单的Open方法带有重载,允许您自己指定access(第二个参数)和共享(第三个参数)。我们可以将OpenReadOpenWrite翻译为Open,因此......

$read = (get-item c:\temp\a.log).OpenRead()
# The following line throws an exception
$write = (get-item c:\temp\a.log).OpenWrite()

... ...变为

$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()

无论你编写它,第三行都将无法创建只写流,因为$read只允许其他流读取。防止这种冲突的一种方法是在打开第二个流之前关闭第一个流:

$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()
}

如果您确实需要同时在同一文件上打开只读和只写流,您始终可以将自己的值传递给Open以允许此操作:

$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')

请注意,共享有两种方式:$read需要在其共享值中包含Write,以便$write可以使用Write访问权限打开,{{1}需要在其共享值中包含$write,因为Read已经通过$read访问权限打开。

在任何情况下,最好在使用完Close()时调用Stream