[英]Using a try block to test if a file is locked in powershell
I want to know if its bad form to use try blocks to test if a file is locked. 我想知道使用try块来测试文件是否被锁定的错误形式。 Here's the background.
这是背景。 I need to send text output of an application to two serial printers simultaneously.
我需要将应用程序的文本输出同时发送到两台串行打印机。 My solution was to use MportMon, and a Powershell script.
我的解决方案是使用MportMon和Powershell脚本。 The way it's supposed to work is the application default prints to the MportMon virtual printer port, which actually makes a uniquely named file in a "dropbox" folder.
它应该起作用的方式是应用程序默认打印到MportMon虚拟打印机端口,该端口实际上在“ dropbox”文件夹中创建一个唯一命名的文件。 The powershell script uses a filesystemwatcher to monitor the folder and when a new file is created, it takes the textual content and pushes it out two serial printers, then deletes the file, so as not to fill up the folder.
Powershell脚本使用filesystemwatcher来监视文件夹,并且在创建新文件时,它将获取文本内容并将其推出两台串行打印机,然后删除该文件,以免填满该文件夹。 I was having a problem when trying to read the text from the file that the virtual printer created.
尝试从虚拟打印机创建的文件中读取文本时遇到问题。 I found that I was getting errors becasue the file was still locked.
我发现由于文件仍被锁定而出现错误。 To fixed the problem, I used a FSM to impliment the logic and instead of checking for a lock everytime before attempting to get the content from the file, I used a try block that attempts to read content from the file, if it fails, the catch block just reaffirms the state that the FSM is in, and the process is repeated until successful.
为了解决该问题,我使用了FSM来实现逻辑,而不是每次尝试从文件中获取内容之前都不检查锁,而是使用try块尝试从文件中读取内容,如果失败,则尝试从文件中读取内容。 catch块只是重申了FSM所在的状态,并且重复该过程直到成功。 It seems to work fine, but I've read somewhere that its bad practice.
看来工作正常,但我在某处读到它的不良做法。 Is there any danger in this method, or is it safe and reliable?
此方法是否存在危险,还是安全可靠? Below is my code.
下面是我的代码。
$fsw = New-Object system.io.filesystemwatcher
$q = New-Object system.collections.queue
$path = "c:\DropBox"
$fsw.path = $path
$state = "waitforQ"
[string]$tempPath = $null
Register-ObjectEvent -InputObject $fsw -EventName created -Action {
$q.enqueue( $event.sourceeventargs.fullpath )
}
while($true) {
switch($state)
{
"waitforQ" {
echo "waitforQ"
if ($q.count -gt 0 ) {$state = "retrievefromQ"}
}
"retrievefromQ" {
echo "retrievefromQ"
$tempPath = $q.dequeue()
$state = "servicefile"
}
"servicefile" {
echo " in servicefile "
try
{
$text = Get-Content -ErrorAction stop $tempPath
#echo "in try"
$text | out-printer db1
$text | out-printer db2
echo " $text "
$state = "waitforQ"
rm $tempPath
}
catch
{
#echo "in catch"
$state = "servicefile"
}
}
Default { $state = "waitforQ" }
}
}
I wouldn't say it's bad practice to test a file to see if it's locked, but it's not as clean as checking the handles used by other processes. 我不会说测试文件以查看是否已锁定是不好的做法,但是它不如检查其他进程使用的句柄那么干净。 Personally I'd test the file like you do, but I adjust a few parts to make it safer/better.
我个人会像您一样测试文件,但会进行一些调整以使其更安全/更好。
Try: 尝试:
$fsw = New-Object system.io.filesystemwatcher
$q = New-Object system.collections.queue
$path = "c:\DropBox"
$fsw.path = $path
$MaxTries = 50 #50times * 0,2s sleep = 10sec timeout
[string]$tempPath = $null
Register-ObjectEvent -InputObject $fsw -EventName created -Action {
$q.enqueue( $event.sourceeventargs.fullpath )
}
while($true) {
if($q.Count -gt 0) {
#Get next file in queue
$tempPath = $q.dequeue()
#Read file
$text = $null
$i = 0
while($text -eq $null) {
#If locked, wait and try again
try {
$text = Get-Content -Path $tempPath -ErrorAction Stop
} catch {
$i++
if($i -eq $MaxTries) {
#Max attempts reached. Stops script
Write-Error -Message "Script is stuck on locked file '$tempPath'" -ErrorAction Stop
} else {
#Wait
Start-Sleep -Milliseconds 200
}
}
}
#Print file
$text | Out-Printer db1
$text | Out-Printer db2
echo " $text "
#Remove temp-file
Remove-Item $tempPath
}
#Relax..
Start-Sleep -Milliseconds 500
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.