使文件夹中的文件过期:在 x 天后删除文件

使文件夹中的文件过期:在 x 天后删除文件

我想在 Windows 共享驱动器中创建一个可供所有人访问的“Drop 文件夹”。如果文件在文件夹中停留的时间超过 X 天,我希望文件会被自动删除。

然而,我发现的所有方法似乎都使用文件的最后修改日期、最后访问时间或创建日期。

我正在尝试将此文件夹设为用户可以将文件放入其中并与他人共享的文件夹。如果有人将文件复制或移动到此处,我希望时钟从此时开始滴答作响。但是,除非有人实际修改了文件,否则文件的上次修改日期和创建日期不会更新。上次访问时间更新得太频繁了……似乎只需在 Windows 资源管理器中打开目录即可更新上次访问时间。

有人知道这个问题的解决办法吗?我认为每天对文件的哈希值进行分类,然后根据超过某个日期的哈希值确定文件的过期日期可能是一个解决方案……但是获取文件的哈希值可能非常耗时。

任何想法都将不胜感激!

笔记:
我已经在这里查看了相当多的答案...研究了文件服务器资源监视器、powershell 脚本、批处理脚本等。它们仍然使用最后访问时间、最后修改时间或创建时间......如上所述,它们不符合上述需求。

答案1

我们结合使用了 powershell 脚本和策略。该策略指定用户必须在 Drop_Zone 共享中创建一个文件夹,然后将他们想要的任何文件复制到该文件夹​​中。当文件夹创建 7 天后(使用 CreationTime),powershell 脚本将删除它。

我还在 powershell 脚本中添加了一些日志记录,以便我们可以验证它的操作,并打开了卷影副本,以拯救完全无能的人。

这是不包含所有日志内容的脚本。

$location = Get-ChildItem \\foo.bar\Drop_Zone
$date = Get-Date
foreach ($item in $location) {
  # Check to see if this is the readme folder
  if($item.PsIsContainer -and $item.Name -ne '_ReadMe') {
    $itemAge = ((Get-Date) - $item.CreationTime).Days
    if($itemAge -gt 7) {
      Remove-Item $item.FullName -recurse -force
    }
  }
  else {
  # must be a file
  # you can check age and delete based on that or just delete regardless
  # because they didn't follow the policy
  }
}

答案2

如果您可以假设 NTFS,则可以将密钥 (Guid) 写入文件的备用流。加上日期,这样您基本上就可以将数据库存储在文件中。

更多信息请访问

http://blogs.technet.com/b/askcore/archive/2013/03/24/alternate-data-streams-in-ntfs.aspx

基本上,您可以将额外的内容存储在用特殊名称编码的单独流中。

答案3

您可以使用 IO.FileSystemWatcher,它允许您“监视”文件夹中是否有新创建的文件。以下是实现此功能所需的部分。

这些变量配置了要监视的路径和用于微调要跟踪的文件的过滤器:

$watchFolderPath = $env:USERPROFILE
$watchFolderFilter = "*.*"

这将设置要监视的文件夹的参数以及事件发生时要执行的操作。基本上,这会在写入每个文件时重置 LastWriteTime:

$watcher = New-Object IO.FileSystemWatcher $watchFolderPath, $watchFolderFilter -Property @{
    IncludeSubdirectories = $true
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
    }
$onCreated = Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action {
    $FileName = $Event.SourceEventArgs.FullPath
    $file = Get-Item $FileName
    $file.LastWriteTime = Get-Date
    }

如果需要,可以使用以下命令取消注册该事件:

Unregister-Event -SourceIdentifier FileCreated

最后,您可以每天运行一次以清理旧文件:

Get-ChildItem $watchFolderPath -Recurse | Where-Object {((Get-Date)-$_.LastWriteTime).TotalDays -gt 6} | Remove-Item

这应该就是你需要的一切...

答案4

无法依赖文件被复制或移动到文件夹的日期。Windows 设法在文件系统、驱动器、网络共享等中保存它。您可能能够使用 Linux 文件服务器解决问题,或者通过使用 FTP 或基于 Web 的上传系统阻止人们直接复制文件。

如果您不介意人们在上传文件后无法修改它们,您可以设置单独的上传和访问文件夹,以及一个在它们之间移动文件并重新设置日期的脚本。但这听起来像是您希望人们能够直接修改文件。

因此,一个简单但有点不靠谱的解决方案就是弄乱日期。我会写两个脚本:

每小时日期更改器脚本

使用您喜欢的语言每小时运行一次脚本,其作用如下:

  • 查找过去 20 年内修改日期的任何文件。
  • 当找到这样的文件时,将其修改日期更改为今天减 20 年。

在 powershell 中,它看起来像这样:

$path = "D:\test"

$today = Get-Date
$before = $today.AddDays(-7300) #356*20 days

Get-ChildItem -Recurse -Path $path | foreach {
    if ($_.LastWriteTime -gt $before) {
        Write-Host $_.Name
        $_.LastWriteTime = $before
    }
}

今天(5 月 27 日)运行此脚本,将所有文件的修改日期设置为 1994 年 6 月 1 日 - 恰好是 356*20 天前。由于它只更改比 $before 值更新的文件,因此它不会触及已设置为过去的文件。

清理脚本

清理脚本会每晚运行一次,并且:

  • 搜索修改日期为“20 年零 X 天前”的文件
  • 删除它们

我不会为这部分编写脚本 - 有很多实用程序可以处理删除早于指定日期的文件,您可以选择任何您喜欢的。 重要的部分是查找 7300+X 天前的文件,其中 X 是您希望自上次修改以来保留它们的天数。

优点

与这里的其他答案相比,这有几个优点:

  • 如果有人修改该文件,计时器将重置。
  • 不需要 NTFS 替代流来标记文件(移动文件时会保留这些文件,因此可能会导致过早删除已修改的文件)
  • 如果有的话,对性能的影响应该很小。无需保留数据库或文件名和/或哈希列表。
  • 如果脚本无法运行,也不会造成严重影响。无需服务或持续运行的程序来更新日期。只需几个计划任务。如果服务失败或遇到竞争条件,依赖于监视新文件并将其上次修改时间更新为现在的解决方案最终可能会删除新文件。

我看到的唯一问题是,如果有人将上次修改时间为 20 年前的文件复制到放置文件夹中。我认为在大多数情况下,这不太可能成为大问题,但可能会出现。

相关内容