简体   繁体   English

如何强制Powershell脚本等待重写文件,直到另一个进程完成读取它为止?

[英]How can I force a Powershell script to wait overwriting a file until another process is finished reading it?

Imagine that I have a shared folder MyShared: 想象一下,我有一个共享文件夹MyShared:

User A, gets the file \\MyShared:\\Foo.txt after every 30 seconds. 用户A每30秒获取一次文件\\ MyShared:\\ Foo.txt。

And I overwrite \\MyShared:\\Foo.txt also after every 28 seconds (within my PowerShell script) 并且每隔28秒(在我的PowerShell脚本中)我也会覆盖\\ MyShared:\\ Foo.txt

How can I prevent myself to overwrite this file while the user is getting it, in PowerShell? 在PowerShell中,如何防止自己在用户获取文件时覆盖该文件? (I do not want to break the content of the file or end-up with some error by attempting to overwrite it in the time of user retrieving it) (我不想在用户检索文件时尝试覆盖它来破坏文件的内容或以一些错误结束文件)

If I rephrase the question : How can I force a Powershell script to wait overwriting a file until another process is finished reading it? 如果我改写这个问题 :如何强制Powershell脚本等待覆盖文件,直到另一个进程完成读取它?

In some cases, you may not be able to overwrite it if the file is open. 在某些情况下,如果文件已打开,则可能无法覆盖它。

Otherwise, you will have to devise some other mechanism to signal that the reader has finished reading it. 否则,您将必须设计一些其他机制来表明阅读器已完成阅读。 This is not really related to powershell. 这与powershell无关。 For example, the reader can create a "lock file" to notify the writer that the file is being read, which it deletes after completing the read. 例如,读取器可以创建一个“锁定文件”以通知写入者该文件正在读取中,读取完成后将删除该文件。 The powershell script can delete the file if the lock file does not exist. 如果锁定文件不存在,则Powershell脚本可以删除该文件。

I use this function to test if file il locked, but in file txt opened by notepad for example the file isn't locked: 我使用此功能来测试文件il是否锁定,但是在记事本打开的txt文件中,例如文件未锁定:

function Test-FileLock {

  param (
        [parameter(Mandatory=$true)]
        [string]$Path
    )

  $oFile = New-Object System.IO.FileInfo $Path    
  if ((Test-Path -Path $Path) -eq $false)
  {
    $false
    return
  }      
  try
  {
      $oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
      if ($oStream)
      {
        $oStream.Close()
      }
      $false
  }
  catch
  {
    # file is locked by a process.
    $true
  }
}

You can use the static Open method in the System.IO.File class. 您可以在System.IO.File类中使用静态Open方法。 If you try open a file and it is being used by another process it will throw an exception, if you wrap it in a try/catch block, you will be able to tell if an exception has been thrown and therefore return $true in the catch block which will mean its in use. 如果您尝试打开一个文件,并且该文件正在被另一个进程使用,它将抛出一个异常;如果将其包装在try / catch块中,您将能够知道是否抛出了异常,因此在捕获块,这意味着它正在使用中。

function Get-FileStatus([string]$Path)
{
     try
     {
        [System.IO.File]::Open($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
        return $false
     }
     catch
     {
        return $true
     }
}



if((Get-FileStatus -Path "C:\myfile.bin"))
{
   Write-Host "File in Use"
}
else
{
   Write-Host "File Not in Use"
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM