Срок действия файлов в папке: удаление файлов через x дней

12

Я пытаюсь создать «Drop Folder» на общем диске Windows, который доступен каждому. Я бы хотел, чтобы файлы автоматически удалялись, если они находятся в папке более X дней.

Однако, похоже, что все методы, которые я нашел для этого, используют дату последнего изменения, время последнего доступа или дату создания файла.

Я пытаюсь сделать из этого папку, в которую пользователь может перетащить файлы, чтобы поделиться с кем-то. Если кто-то скопирует или переместит сюда файлы, я бы хотел, чтобы часы начали тикать в этот момент. Тем не менее, дата последнего изменения и дата создания файла не будут обновлены, если кто-то фактически не изменяет файл. Время последнего доступа обновляется слишком часто ... кажется, что простое открытие каталога в проводнике Windows обновит время последнего доступа.

Кто-нибудь знает решение этой проблемы? Я думаю, что каталогизация хэша файлов на ежедневной основе, а затем истечение срока действия файлов на основе хэшей, старше определенной даты, может быть решением .... но получение хэшей файлов может занять много времени.

Благодарим за любую идею!

Примечание:
я уже рассмотрел довольно много ответов здесь ... просмотрел монитор ресурсов файлового сервера, сценарии powershell, пакетные сценарии и т. Д. Они по-прежнему используют время последнего доступа, время последнего изменения или время создания ... которые, как описано, не соответствуют вышеуказанным потребностям.

Бретт Дж
источник
Один вопрос, как упомянул @Michael Kjorling, останавливает ли таймер подсчет, если файл был изменен после того, как был уронен в коробку?
Get-HomeByFiveOClock
Что вы ищете, так это Windows tmpwatch.
Эйвери Пейн

Ответы:

5

Мы использовали комбинацию сценария 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
  }
}
murisonc
источник
1
Это кажется самым простым, оно не связано с отметкой даты и времени файла, альтернативными потоками данных и не требует какого-либо списка файлов и дат их удаления. Я собирался создать потрясающий сценарий, который делал все виды магии, но потом я увидел это.
BeowulfNode42
и не требует, чтобы сценарий отслеживания файловой системы запускал сценарий постоянно, так как он может запускаться один раз в день, и не имеет большого значения, если по какой-либо причине пропущен день.
BeowulfNode42
2
Отличная простая идея, как и @ BeowulfNode42. Чтобы пользователи могли создавать папки, простое «Запретить» из ACL «Создать файлы / записать данные» в «Только эта папка» гарантирует, что пользователи также должны создавать подпапки.
Бретт Дж
3

Если вы можете использовать NTFS, вы можете записать ключ (Guid) в альтернативный поток файла. Плюс дата, чтобы вы могли хранить базу данных в файлах.

Более подробную информацию можно найти на

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

По сути, вы можете хранить дополнительный контент в отдельном потоке, который кодируется специальным именем.

TomTom
источник
Как можно это сделать?
Бретт Дж
@BrettG Добавлена ​​ссылка на документацию. «Альтернативный поток данных NTFS» заставил бы вас найти его и в Google, на всякий случай - вы не знаете Google.
TomTom
Извините, я знаю, что такое альтернативные потоки данных, я просто пытался понять их использование в этом контексте. Таким образом, вы говорите, вместо того, чтобы использовать хеш или что-то еще, используйте GUID (и / или дату) в альтернативном потоке данных для отслеживания файлов ... ага.
Бретт Дж
Да. Если вы можете надежно МАРКИРОВАТЬ файл - вы даже можете поместить в него дату маркировки - тогда вам не нужно вычислять хеш.
TomTom
Просто следите, если файл скопирован из хранилища, отредактирован, а затем скопирован обратно. Затем вы хотите перезапустить таймер, для чего может быть полезен хеш.
CVn
2

Вы можете использовать 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

Это должно быть все, что вам нужно ...

Тим Феррилл
источник
Отредактировал это, чтобы установить атрибут LastWriteTime при создании файла, а затем использовать его для последующего удаления файлов.
Тим Феррилл
1

Это было какое-то время, но я создал относительно простой метод решения этой проблемы.

Я бы коснулся любых файлов, добавленных в каталог для удаления (отслеживаемых с помощью утилиты мониторинга ресурсов), и установил дату последнего изменения на дату, добавленную в папку.

Затем я мог бы использовать дату последнего изменения для очистки любых файлов, которые должны быть удалены. Это также имеет то преимущество, что если кто-то действительно обновит файл, он сбросит обратный отсчет.

Тим Бригам
источник
Идеальная идея Я проведу собственное исследование ... но есть идеи, какую утилиту для мониторинга ресурсов вы использовали?
Бретт Дж
@BrettG честно говоря, это было почти 10 лет назад. Я не могу вспомнить Ты заставляешь меня чувствовать себя старым. :) Если бы я сделал это сегодня, я бы выполнил задание на основе событий аудита файловой системы в средстве просмотра событий. Я думаю, что объект FileSystemWatcher .NET доступен через PowerShell. Это был бы другой вариант.
Тим Бригам
Ха, я не понимал, что ты имел в виду так долго, когда сказал "некоторое время". Да, достаточно забавно, я просто смотрю на FileSystemWatcher. Хотя я не думаю, что это будет работать с перемещенными / скопированными файлами. Спасибо за ответ!
Бретт Дж
1
@BrettG - Файловая система может использоваться вместе с таблицей отслеживания, но у нее есть свои проблемы. См. Здесь: stackoverflow.com/questions/1764809/… stackoverflow.com/questions/6000856/filesystemwatcher-issues
JohnP
1
@BrettG - Кроме того, это хорошее расширение для FSW: codeproject.com/Articles/58740/…
JohnP
1

Невозможно полагаться на даты, когда файл был скопирован или перемещен в папку. Windows удается сохранить его на файловых системах, дисках, сетевых ресурсах и т. Д. Возможно, вы сможете что-то решить с файловым сервером linux или запретить людям напрямую копировать файлы с помощью FTP или системы загрузки через Интернет.

Если вы согласны с тем, что люди не могут изменять файлы после их загрузки, у вас могут быть отдельные папки для загрузки и доступа, а также скрипт, который перемещает файлы между ними и обновляет их. Но, похоже, вы хотите, чтобы люди могли напрямую изменять файлы.

Таким образом, простое, хотя и несколько хакерское решение - связываться с датами. Я бы написал два сценария:

Почасовой скрипт Changer

Сценарий должен запускаться раз в час или около того на выбранном вами языке, который:

  • Ищет любой файл с датой, измененной за последние 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
    }
}

Запуск этого сценария сегодня (27 мая) устанавливает дату изменения всех файлов 1 июня 1994 года - ровно 356 * 20 дней назад. Поскольку он изменяет только файлы, которые новее значения $ before, он не затрагивает файлы, которые он уже установил в прошлом.

Скрипт очистки

Скрипт очистки запускается каждую ночь и:

  • Поиск файлов с измененной датой "20 лет и X дней назад"
  • Удалить их

Я не буду писать сценарий для этой части - существует множество утилит, которые могут обрабатывать удаление файлов, которые старше указанной даты, выбирайте то, что вам нравится. Важной частью является поиск файлов, которым 7300 + X дней, где X - количество дней, в которые вы хотите сохранить их с момента их последнего изменения.

преимущества

Это имеет несколько преимуществ перед другими ответами здесь:

  • Таймер сбрасывается, если кто-то изменяет файл.
  • Нет необходимости в альтернативных потоках NTFS для маркировки файлов (которые сохраняются при перемещении файла, поэтому могут привести к преждевременному удалению измененного файла)
  • Должен иметь минимальное влияние на производительность. Нет необходимости вести базу данных или список имен файлов и / или хэшей.
  • Ничто не сломается ужасно, если сценарии не запускаются. Для обновления даты нет службы или постоянно запущенной программы. Всего пара запланированных заданий. Решения, основанные на наблюдении за новыми файлами и обновлении их последнего измененного времени до настоящего времени, могут в конечном итоге удалить новые файлы, если служба выйдет из строя или перейдет в состояние состязания.

Единственная проблема, которую я вижу, - это если люди копируют файл, который был последний раз изменен 20 лет назад, в папку удаления. Я думаю, что в большинстве сценариев это вряд ли будет большой проблемой, но может возникнуть.

Грант
источник
0

Вы можете формализовать добавление файлов в выпадающий список через веб-страницу, которая имеет «загружать» IFRAME. Затем пользователь может «опубликовать» файл, который вызывает задание PHP / ASP на сервере, который берет файл и помещает его в расположение сборщика. PHP / ASP может выполнять любое количество операций индексирования / анализа.

Саймон Кэтлин
источник
0

Если кто-то скопирует или переместит сюда файлы, я бы хотел, чтобы часы начали тикать в этот момент. Тем не менее, дата последнего изменения и дата создания файла не будут обновлены, если кто-то фактически не изменяет файл.

Я хотел бы создать сценарий, который запускается как запланированные задачи каждые пять минут и выполняет две вещи.

  1. Первым действием будет создание копии любого файла, скопированного в папку, добавление префикса к файлу и удаление оригинала. Это гарантирует, что дата создания файла была единой для приложения.
  2. Второе действие будет смотреть на все файлы с предопределенным префиксом (установленным с действием 1) и удалять любые из них с датой создания старше X дней. Это решило бы проблему изменения / даты обращения.
user1914368
источник
0

Существует существующий механизм для пометки файлов, бит Archive. Он был там с первых дней существования DOS и присутствует как в FAT, так и в NTFS.

По сути, для каждого файла установлен архивный бит по умолчанию. Если вы видите файл с битом архива в папке удаления, (1) очистите этот бит и (2) установите его дату на сегодня. Если вы видите файл без этого бита и с датой <= 7 дней в прошлом, удалите его.

Если пользователь записывает в файл, пока он находится в папке удаления, его архивный бит устанавливается снова, поэтому его время жизни также сбрасывается на 7 дней. В конце концов, это новый файл.

Теперь вы можете безопасно использовать FileSystemWatcher. Любые проблемы, которые у него есть (например, повторяющиеся события, переполнение буфера, потеря подробной информации), больше не имеют значения, так как соответствующая информация находится в метаданных файла.

MSalters
источник