Loading [MathJax]/jax/output/CommonHTML/config.js
社区首页 >问答首页 >PowerShell文件监视器寄存器-ObjectEvent-等待文件完成复制

PowerShell文件监视器寄存器-ObjectEvent-等待文件完成复制
EN

Stack Overflow用户
提问于 2020-06-12 11:07:26
回答 3查看 1.3K关注 0票数 1

下面的代码正在检查指定目录$folderCompleted中的新文件。

当前,当一个小文件被放置到该目录(~1MB)中时,移动项命令和其他文件读取检查将成功完成。

但是,当一个大文件被移动到这个目录中时,在文件被完全移动(复制)到该目录之前,将调用对象事件。这将导致文件检查和移动项命令失败,因为该文件仍在使用中。

代码语言:javascript
代码运行次数:0
复制
# File Watcher
$filter = '*.*'
$fsw = New-Object IO.FileSystemWatcher $folderCompleted, $filter -Property @{
    IncludeSubdirectories = $true
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}

$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
    $path = $Event.SourceEventArgs.FullPath
    $name = $Event.SourceEventArgs.Name
    $changeType = $Event.SourceEventArgs.ChangeType
    $timeStamp = $Event.TimeGenerated
    Write-Host "The file '$name' was $changeType at $timeStamp"

    # File Checks

    # Move File
    Move-Item $path -Destination $destinationPath -Verbose
}

如何进行检查,以确定文件是否仍在复制?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-13 14:01:16

在上面贴出我的评论后不久就解决了这个问题。其他答案可能相似,但最终将此函数添加到脚本顶部。

代码语言:javascript
代码运行次数:0
复制
# function Test-FileLock 
function Test-FileLock {
  param ([parameter(Mandatory=$true)][string]$Path)

  $oFile = New-Object System.IO.FileInfo $Path

  if ((Test-Path -Path $Path) -eq $false)
  {
    return $false
  }

  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.
    return $true
  }
}

在$onCreated部分的变量部分之后添加此代码。

代码语言:javascript
代码运行次数:0
复制
# Test File Lock
Do {
    $filetest = Test-FileLock -Path $path
    sleep -Seconds 5
} While ($filetest -eq $true)
票数 2
EN

Stack Overflow用户

发布于 2020-06-13 03:44:19

尝尝这个。(以前也有类似的担忧)。

事件触发器是在同步哈希表中收集所有受影响的项,附加的scriptblock处理所有项,但只有当它们准备好读取而不是锁定时才会处理文件。如果文件被锁定,您将在控制台中看到它。只需尝试复制一个文件>1GB,并观察输出。

脚本块$fSItemEventProcessingJob处理这些项(比如复制到备份文件),最初创建它是为了将其用于“开始-作业”。但是您无法访问和修改会话中的该后台作业中的哈希表。因此,它是一个简单的scriptblock执行。

要停止所有操作,只需按CTRL + C键即可。这仍然会执行"finally“块,取消注册并处理所有内容。

PS:脚本只是一个测试,只在我的PC上进行本地测试。

代码语言:javascript
代码运行次数:0
复制
Clear-Host
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop


$fileSystemWatcherDirPath = 'C:\temp'
$fileSystemWatcherFilter = '*.*'

$fileSystemWatcher = [System.IO.FileSystemWatcher]::new($fileSystemWatcherDirPath , $fileSystemWatcherFilter)
$fileSystemWatcher.IncludeSubdirectories = $true
$fileSystemWatcher.EnableRaisingEvents = $true
$fileSystemWatcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor [System.IO.NotifyFilters]::DirectoryName -bor [System.IO.NotifyFilters]::LastWrite  # [System.Linq.Enumerable]::Sum([System.IO.NotifyFilters].GetEnumValues())

# Create syncronized hashtable
$syncdFsItemEventHashT = [hashtable]::Synchronized([hashtable]::new())

$fileSystemWatcherAction = {
    try {
        $fsItemEvent = [pscustomobject]@{
            EventIdentifier  = $Event.EventIdentifier
            SourceIdentifier = $Event.SourceIdentifier
            TimeStamp        = $Event.TimeGenerated
            FullPath         = $Event.SourceEventArgs.FullPath
            ChangeType       = $Event.SourceEventArgs.ChangeType
        }

        # Collecting event in synchronized hashtable (overrides existing keys so that only the latest event details are available)
        $syncdFsItemEventHashT[$fsItemEvent.FullPath] = $fsItemEvent
    } catch {
        Write-Host ($_ | Format-List * | Out-String ) -ForegroundColor red
    }
}


# Script block which processes collected events and do further actions like copying for backup, etc...
# That scriptblock was initially used to test "Start-Job". Unfortunately it's not possible to access and modify the synchronized hashtable created within this scope.
$fSItemEventProcessingJob = {
    $keys = [string[]]$syncdFsItemEventHashT.psbase.Keys

    foreach ($key in $keys) {
        $fsEvent = $syncdFsItemEventHashT[$key]

        try {
            # in case changetype eq DELETED or the item can't be found on the filesystem by the script -> remove the item from hashtable without any further actions.
            # This affects temporary files from applications. BUT: Could also affect files with file permission issues.
            if (($fsEvent.ChangeType -eq [System.IO.WatcherChangeTypes]::Deleted) -or (! (Test-Path -LiteralPath $fsEvent.FullPath)) ) {
                $syncdFsItemEventHashT.Remove($key )
                Write-Host ("==> Item '$key' with changetype '$($fsEvent.ChangeType)' removed from hashtable without any further actions!") -ForegroundColor Blue
                continue
            }

            # get filesystem object
            $fsItem = Get-Item -LiteralPath $fsEvent.FullPath -Force

            if ($fsItem -is [System.IO.FileInfo]) {
                # file processing

                try {
                    # Check whether the file is still locked / in use by another process
                    [System.IO.FileStream]$fileStream = [System.IO.File]::Open( $fsEvent.FullPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::Read)
                    $fileStream.Close()
                } catch [System.IO.IOException] {
                    Write-Host ("==> Item '$key' with changetype '$($fsEvent.ChangeType)' is still in use and can't be read!") -ForegroundColor Yellow
                    continue
                }
            } elseIf ($fsItem -is [System.IO.DirectoryInfo]) {
                # directory processing
            }

            $syncdFsItemEventHashT.Remove($key )
            Write-Host ("==> Item '$key' with changetype '$($fsEvent.ChangeType)' has been processed and removed from hashtable.") -ForegroundColor Blue

        } catch {
            Write-Host ($_ | Format-List * | Out-String ) -ForegroundColor red
        }
    }
}

[void] (Register-ObjectEvent -InputObject $fileSystemWatcher -EventName 'Created' -SourceIdentifier 'FSCreated' -Action $fileSystemWatcherAction)
[void] (Register-ObjectEvent -InputObject $fileSystemWatcher -EventName 'Changed' -SourceIdentifier 'FSChanged' -Action $fileSystemWatcherAction)
[void] (Register-ObjectEvent -InputObject $fileSystemWatcher -EventName 'Renamed' -SourceIdentifier 'FSRenamed' -Action $fileSystemWatcherAction)
[void] (Register-ObjectEvent -InputObject $fileSystemWatcher -EventName 'Deleted' -SourceIdentifier 'FSDeleted' -Action $fileSystemWatcherAction)



Write-Host "Watching for changes in '$fileSystemWatcherDirPath'.`r`nPress CTRL+C to exit!"
try {
    do {
        Wait-Event -Timeout 1

        if ($syncdFsItemEventHashT.Count -gt 0) {
            Write-Host "`r`n"
            Write-Host ('-' * 50) -ForegroundColor Green
            Write-Host "Collected events in hashtable queue:" -ForegroundColor Green
            $syncdFsItemEventHashT.Values | Format-Table | Out-String
        }

        # Process hashtable items and do something with them (like copying, ..)
        .$fSItemEventProcessingJob

        # Garbage collector
        [GC]::Collect()

    } while ($true)

} finally {
    # unregister
    Unregister-Event -SourceIdentifier 'FSChanged'
    Unregister-Event -SourceIdentifier 'FSCreated'
    Unregister-Event -SourceIdentifier 'FSDeleted'
    Unregister-Event -SourceIdentifier 'FSRenamed'

    # dispose
    $FileSystemWatcher.Dispose()
    Write-Host "`r`nEvent Handler removed."
}
票数 1
EN

Stack Overflow用户

发布于 2020-06-13 00:48:55

您需要构建一个测试,以查看文件是否被锁定(仍在复制)。为此,您可以使用以下函数:

代码语言:javascript
代码运行次数:0
复制
function Test-LockedFile {
    param (
        [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('FullName', 'FilePath')]
        [ValidateScript({Test-Path $_ -PathType Leaf})]
        [string]$Path
    )
    $file = [System.IO.FileInfo]::new($Path)
    # old PowerShell versions use:
    # $file = New-Object System.IO.FileInfo $Path

    try {
        $stream = $file.Open([System.IO.FileMode]::Open,
                             [System.IO.FileAccess]::ReadWrite,
                             [System.IO.FileShare]::None)
        if ($stream) { $stream.Close() }
        return $false
    }
    catch {
        return $true
    }
}

如果在当前代码之上的某个位置设置了该功能,则可以:

代码语言:javascript
代码运行次数:0
复制
# File Checks
while (Test-LockedFile $path) {
    Start-Sleep -Seconds 1
}

# Move File
Move-Item $path -Destination $destinationPath -Verbose
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62350872

复制
相关文章
powershell修改host文件
使用图形界面发现修改不了host文件,这里提供一种方法: 1.按win+X组合键 2.点击Wodows PowerShell(管理员) 3.输入 cd C:\Windows\System32\drivers\etc
全栈程序员站长
2022/11/07
1.9K0
powershell修改host文件
Python文件复制
#!/usr/bin/python# -*- coding: UTF-8 -*-import osimport shutil# 创建的目录root_path = "D:\paper\\5derain\CIR\CIR_delete\pairimages"copy_path = "D:\paper\\5derain\CIR\CIR_delete\pairimages\\train"for i in range(2965): source_file = root_path + "\\" + str(i+1)
狼啸风云
2020/08/27
1.4K0
nodejs复制文件
const path = require('path') const fs = require('fs') const arr = ['PLDO201941060204M05775张晓光', 'PLDO201941060204M04723王兆祎', 'PLDO201941060204M05776魏博晨', 'PLDO201941060204M04351朱治宋', 'PLDO201941060204M06014刘艳芳', 'PLDO201941060204M03948王盈安' ]; const
2021/11/08
1.3K0
php安装完成以后要复制php.ini文件
直接#find  /-namephp.ini找不到,是因为安装php的时候没有复制配置文件PHP
Java架构师必看
2021/03/22
5270
cmd复制文件
SET SourceFile=G:\Jmeter\apache-jmeter-5.0\report\backup\result.jtl
用户8249384
2022/04/04
9970
python 3.3 复制文件 或 文件
注意: 运行第一遍,会出现 copy sucess; 运行第二遍, copytree 会报错,因为 目标目录已存在
py3study
2020/01/06
1.5K0
python 3.3 复制文件 或 文件
linux怎么将文件复制到别的文件_linux 文件夹复制
本文主要讲解linux怎么复制文件到其他文件夹。 在Linux和Unix系统上工作时,复制文件和目录是您每天要执行的最常见任务之一。 cp是一个命令行实用程序,用于复制Unix和Linux系统上的文件和目录。在本文中,我们将解释如何使用cp命令。
全栈程序员站长
2022/09/23
10.7K0
Kubernetes等待部署完成
在CI/CD的时候,我们有时候需要等待部署完成,pod已经正常运行后,再进入容器执行一些命令,例如laravel环境下,我们需要等pod起来后,再执行migrate。
少羽大怪兽
2020/11/12
1K0
Python: 复制文件和文件夹
文章背景: 工作中,经常需要拷贝数据,比如将仪器数据拷贝到指定路径。Python中的shutil模块可以用于文件和文件夹的复制。此外,也可以借助win32file模块来复制文件。
Exploring
2022/09/20
4.2K0
FileStream大文件复制
      FileStream缓冲读取和写入可以提高性能。FileStream读取文件的时候,是先讲流放入内存,经Flash()方法后将内存中(缓冲中)的数据写入文件。如果文件非常大,势必消耗性能。特封装在FileHelper中以备不时之需。参考文章:http://www.cnblogs.com/yangxiaohu1/archive/2008/06/20/1226949.html将该文章中提供的代码少做修改,原文中进行了强制类型转换,如果文件很大,比如4G,就会出现溢出的情况,复制的结果字节丢失严重,导致复制文件和源文件大小不一样。这里修改的代码如下:
跟着阿笨一起玩NET
2018/09/19
1.5K0
FileStream大文件复制
使用Python复制文件
最近公司在进行应用拆分,将一个系统拆分为多个应用,但中间的过渡时间却是很难受的,即:修改了老项目,要把修改的代码复制到新系统里,
拿我格子衫来
2022/01/24
1.2K0
python文件操作--复制
文件的写入 和文件的读取一样,文件的写入也有多种方法,write()和writelines()方法。 二者之间的区别是: write()方法用于将字符串写入文件,如果要写入文件的字符串不多,使用write()方法即可,
py3study
2020/01/15
1.2K0
[Python文件操作案例] - 复制大小文件
1、使用open函数打开两个文件,一个是源文件,一个是目标文件,原文件只读方式打开,目标文件只写方式打开
python自学网
2022/10/08
1.1K0
[Python文件操作案例] - 复制大小文件
文件夹复制
 public static void copyDirectory(File src, File dest) throws IOException {   File newFile = new File(dest, src.getName());   newFile.mkdir();   File[] file1 = src.listFiles();   for (File file : file1) {    if (file.isFile()) {     BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));     BufferedOutputStream bos = new BufferedOutputStream(       new FileOutputStream(new File(newFile,file.getName())));     int b;     while ((b = bis.read()) != -1) {      bos.write(b);     }     bis.close();     bos.close();    }else{     copyDirectory(file, newFile);    }   }  }
秋白
2019/02/21
2.5K0
将PowerShell脚本编码到PNG文件
Invoke-PSImage接收一个PowerShell脚本,并将脚本的字节编码为PNG图像的像素。它生成一个oneliner,用于从文件或从网络上执行。
Khan安全团队
2021/03/10
1.3K0
字节流---复制文件和文件夹
复制文件 封装后的复制文件方法 接收参数为两个File对象,代表输入和输出文件,并声明抛出IOException异常 public static void CopyFile(File src, File dest) throws IOException; 判断是否为文件夹,如果是文件夹则抛出异常 if (src.isDirectory()) { throw new IOException("这是一个文件夹"); } 建立输入输出流 InputStream iStream = new Fil
shimeath
2020/07/30
6890
Linux 文件I/O操作(简单实现文件复制)
       简单的实现一下文件的复制操作,直接贴源码了,中间也有一些注释,至于更多的详细的命令参数,推荐看下这篇博客,讲的很详细:传送门
Ch_Zaqdt
2020/02/24
2.2K0
MPQ 文件系统完成
基于StormLib, 参考N3的ZipFileSystem实现了一个MpqFileSystem 有一点要注意, 文件路径里不能用'/', 都要用'//' @_@ mpq文件包里的文件是不保存文件名(
逍遥剑客
2018/05/23
3600
MPQ 文件系统完成
基于StormLib, 参考N3的ZipFileSystem实现了一个MpqFileSystem
逍遥剑客
2019/02/20
7730
点击加载更多

相似问题

等待文件复制/上载完成

220

Delphi等待文件复制过程完成

13

文件监视器等待不使用线程的完整文件夹复制

20

正在等待Firefox扩展中的文件复制完成

10

Powershell:在文件完成复制后执行脚本

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档