zoukankan      html  css  js  c++  java
  • 监控目录下的文件操作与实时同步

    若有个需求:要求记录下某个目录下的所有操作,包括创建文件、修改文件、重命名、删除文件的操作,将以上所有的操作全部记录到日志中,或者做其他操作。.NET提供了一个方法叫做“System.IO.FileSystemWatcher”,方便powershell来调用。具体使用方法,我慢慢解释。


     一、监控某个目录下的所有操作

    方案一:

    $folder = "c:	est"  #定义要监控哪个目录
    $timeout = 1000  #设置监控的时间间隔
    $filesystemwatcher = new-object System.IO.FileSystemWatcher $folder  #使用FileSystemWatcher方法开启文件监控
    echo "ctrl+c will exit" while ($true) { $result = $filesystemwatcher.WaitForChanged("all",$timeout)  #监控种类,all代表监控所有操作,$timeout表示监控的时间间隔 if($result.TimedOut -eq $false)    #$result.TimedOut返回true或false,若目录下不操作返回true,
    { $time = date -UFormat "%Y-%m-%d %H-%M-%S" $type = $result.ChangeType $name = $result.Name $oldname = $result.OldName echo "$time $type $name $oldname " #显示如下信息,时间、 操作的类型、操作文件的名称、操作文件原来的名称,只有重命名后才会显示 } }

      测试:

      在c: est目录下增删改查一些文件

      终端返回的结果: 

      在所执行的终端执行ctrl+c或者关闭终端即可终止监控程序。

    方案二:

      该方案与方案一不同的一点是,方案二会在后台运行,但方案一由while循环运行。

    $watcher = New-Object System.IO.FileSystemWatcher  #启动监控实例
    $watcher.Path = "c:	est"  #监控的路径
    $watcher.IncludeSubdirectories = $true     #是否监控子目录下的文件操作
    $watcher.EnableRaisingEvents = $true      #默认是true
    
    #重写changed、created、deleted、renamed方法 $changed = Register-ObjectEvent $watcher "Changed" -Action {   $time = date -UFormat "%Y-%m-%d %H-%M-%S" write-host " $time Changed: $($eventArgs.FullPath)" } $created = Register-ObjectEvent $watcher "Created" -Action { $time = date -UFormat "%Y-%m-%d %H-%M-%S" write-host "$time Created: $($eventArgs.FullPath)" } $deleted = Register-ObjectEvent $watcher "Deleted" -Action { $time = date -UFormat "%Y-%m-%d %H-%M-%S" write-host "$time Deleted: $($eventArgs.FullPath)" } $renamed = Register-ObjectEvent $watcher "Renamed" -Action { $time = date -UFormat "%Y-%m-%d %H-%M-%S" write-host "$time Renamed: $($eventArgs.FullPath)" }

      测试:

      在被监控的目录下增删改查操作

    返回的结果:

    但是方案二退出与方案一的不一致。

      1、退出当前执行的终端,可以退出整个监控程序

      2、手动注销事件,注销以上重新的方法,需要在程序运行的终端执行

    Unregister-Event $changed.Id
    Unregister-Event $created.Id
    Unregister-Event $deleted.Id
    Unregister-Event $renamed.Id
    

      红框内的内容是输入进去的。

    二、实时同步

      有了目录监控的能力,可以扩展一下,实现文件实时同步。

      有两个目录,目录A中凡是有了任何操作,便同步到B目录中,实现实时同步。具体代码如下:

    【注意】

      代码中监听操作的时间隔是1000ms,若两相邻操的时间间隔作小于1000ms时,就会出现不同步的问题

    $folder = "\share-server	"  #监听的源目录
    $timeout = 1000  #时间间隔,ms
    $filesystemwatcher = new-object System.IO.FileSystemWatcher $folder
    $filesystemwatcher.IncludeSubdirectories = $true  #开启监听子目录的功能
    $des = "c:	est"  #同步的目标目录
    $logpath = "c:	estlogsa.log"  #日志记录的位置,需要提前创建好日志的父目录
    
    echo "ctrl+c will exit"
    cp -Force -Recurse $folder* $des  #先将源目录中的所有文件拷贝到子目录中
    
    while ($true)  #开启监听
    {
        $result = $filesystemwatcher.WaitForChanged("all",$timeout)
        if($result.TimedOut -eq $false)
        {
            $time = date -UFormat "%Y-%m-%d %H:%M:%S"  
            $type = $result.ChangeType
            $name = $result.Name
            $oldname = $result.OldName
            echo "$time  $type      $name    oldname:$oldname "  >> $logpath  #输出日志
               
            $isfile = $true
            $filefullpath = $folder + "" + $name  #源文件的全路径
            $dstpath = $des + "" + $name      #目标文件的全路劲
    
            if( Test-Path $filefullpath ){ $filepath = $filefullpath }  #当删除时,源文件的全路径不存在,需要借助目标文件的全路径来判断是文件还是目录
            if( Test-Path $dstpath ){ $filepath = $dstpath }
    
            if ( (ls $filepath) -is [IO.fileinfo])   #判断是文件还是目录
            {
               $isfile = $true  
            }
            else
            {
               $isfile = $false
            }
    
        #根据不同的操作类型做出不同的操作
            if( $type -eq "Changed" ) 
            {   
              if( $isfile )
              {
                cp $filefullpath $dstpath
                echo "cp $filefullpath $dstpath"  >> $logpath
              }
            }
    
            if( $type -eq "Created" ) 
            {
              if( $isfile )
              {
                New-Item $dstpath
                echo "cp $filefullpath $des"  >> $logpath
              }
              else
              {
                mkdir $dstpath
                echo "mkdir $dstpath"  >> $logpath
              }
            }
    
            if( $type -eq "Deleted" ) 
            {
              rm -Recurse -Force $dstpath
              echo "rm $dstpath"  >> $logpath
            }
    
            if( $type -eq "Renamed" ) 
            {
              cd $des
              mv $oldname $name
              echo "mv $oldname $name"  >> $logpath
            }
        }
    }
    

      测试:

      日志结果:

    【注意】

      以上代码存在一个缺陷,当文件在不同的目录下移动时,会有异常,只有修改一下代码逻辑便可实现。

  • 相关阅读:
    nginx超时问题
    linux打包文件,压缩文件
    centos查看文件夹大小
    Nginx反向代理和负载均衡
    nginx的location配置详解
    nginx错误Upstream timed out
    mysql处理函数
    SQL左右连接中的on and和on where的区别
    html select change事件触发
    get,post区别
  • 原文地址:https://www.cnblogs.com/zqj-blog/p/10305453.html
Copyright © 2011-2022 走看看