Я хочу создать «Папку для перетаскивания» на общем диске Windows, доступную для всех. Я бы хотел, чтобы файлы удалялись автоматически, если они находятся в папке более X дней.
Однако похоже, что все методы, которые я нашел для этого, используют дату последнего изменения, время последнего доступа или дату создания файла.
Я пытаюсь сделать это папкой, в которую пользователь может помещать файлы, чтобы поделиться с кем-нибудь. Если кто-то копирует или перемещает сюда файлы, я бы хотел, чтобы часы начали отсчитывать отсчет. Однако дата последнего изменения и дата создания файла не будут обновлены, если кто-то не изменит файл. Время последнего доступа обновляется слишком часто ... кажется, что простое открытие каталога в проводнике Windows обновит время последнего доступа.
Кто-нибудь знает решение этого? Я думаю, что ежедневная каталогизация хэшей файлов с последующим истечением срока хранения файлов на основе хэшей старше определенной даты может быть решением ... но получение хэшей файлов может занять много времени.
Благодарим за любую идею!
Примечание:
Я уже просмотрел довольно много ответов здесь ... посмотрел на монитор ресурсов файлового сервера, сценарии PowerShell, пакетные сценарии и т. Д. Они все еще используют время последнего доступа, время последнего изменения или время создания ... которое, как описано, не соответствуют вышеуказанным требованиям.
Мы использовали комбинацию сценария 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
}
}
Если вы можете предположить NTFS, вы можете записать ключ (Guid) в альтернативный поток файла. Плюс дата, чтобы вы могли хранить базу данных в файлах.
Более подробную информацию можно найти на сайте
http://blogs.technet.com/b/askcore/archive/2013/03/24/alternate-data-streams-in-ntfs.aspx
В принципе, вы можете хранить дополнительный контент в отдельном потоке, который кодируется специальным именем.
Вы можете использовать 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
Это должно быть все, что вам нужно ...
Невозможно полагаться на даты, когда файл был скопирован или перемещен в папку. Windows удается сохранить его в файловых системах, на дисках, в общих сетевых ресурсах и т. Д. Вы можете что-то решить с файловым сервером Linux или запретить людям напрямую копировать файлы с помощью FTP или веб-системы загрузки.
Если вас устраивает то, что люди не могут изменять файлы после их загрузки, у вас могут быть отдельные папки для загрузки и доступа, а также сценарий, который перемещает файлы между ними и меняет их дату. Но похоже, что вы хотите, чтобы люди могли напрямую изменять файлы.
Итак, простое, хотя и несколько хитрое решение - это испортить даты. Я бы написал два сценария:
Запустите сценарий примерно раз в час на предпочитаемом вами языке, чтобы:
В 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, он не будет касаться файлов, которые уже установили в прошлое.
Скрипт очистки будет запускаться каждую ночь и:
Я не буду писать сценарий для этой части - существует множество утилит, которые могут обрабатывать удаление файлов, которые старше указанной даты, выберите то, что вам нравится. Важной частью является поиск файлов возрастом 7300+ X дней, где X - количество дней, в течение которых вы хотите их хранить с момента последнего изменения.
У этого есть несколько преимуществ перед другими ответами здесь:
Единственная проблема, которую я вижу, заключается в том, что люди копируют файл, последний раз измененный 20 лет назад, в папку для размещения. Я думаю, что в большинстве сценариев это вряд ли будет большой проблемой, но может возникнуть.
Прошло время, но я создал относительно простой метод решения этой проблемы.
Я бы коснулся любых файлов, добавленных в каталог размещения (отслеживаемых с помощью утилиты мониторинга ресурсов), и установил бы дату последнего изменения на дату добавления в папку.
Затем я мог бы использовать дату последнего изменения, чтобы удалить все файлы, которые нужно удалить. Это также имеет то преимущество, что, если кто-то действительно обновит файл, он сбросит обратный отсчет.
Вы можете формализовать добавление файлов в раскрывающийся список через веб-страницу, на которой есть IFRAME для «загрузки». Затем пользователь может «опубликовать» файл, который вызывает задание PHP / ASP на сервере, который берет файл и помещает его в место для складывания. PHP / ASP может выполнять любое количество операций индексации / анализа.
Если кто-то копирует или перемещает сюда файлы, я бы хотел, чтобы часы начали отсчитывать отсчет. Однако дата последнего изменения и дата создания файла не будут обновлены, если кто-то фактически не изменит файл.
Я бы создал сценарий, который запускается как запланированные задачи каждые пять минут и выполняет две функции.
Есть уже существующий механизм для пометки файлов, бит архива. Он существует с первых дней существования DOS и присутствует как в FAT, так и в NTFS.
По сути, для каждого файла по умолчанию установлен бит архива. Если вы видите файл с участием бит архива в папке размещения, (1) очистите этот бит и (2) установите его дату на сегодняшний день. Если вы видите файл без этот бит и с датой <= 7 дней назад удалите его.
Если пользователь записывает в файл, пока он находится в папке для размещения, его бит архива устанавливается снова, поэтому его время жизни также сбрасывается до 7 дней. В конце концов, это новый файл.
Теперь вы можете безопасно использовать FileSystemWatcher. Любые проблемы (например, повторяющиеся события, потеря подробной информации из-за переполнения буфера) больше не имеют значения, поскольку вся соответствующая информация содержится в метаданных файла.