2009-07-16 2 views
5

У меня есть каталог, который постоянно заполняется файлами «артефакт». Многие разные программы сбрасывают свои временные файлы в этом каталоге, и маловероятно, что эти программы скоро станут самоочищающимися.Какой самый эффективный метод непрерывного удаления файлов старше X часов в Windows?

Между тем, я хотел бы написать программу, которая постоянно удаляет файлы в этом каталоге по мере их устаревания, которые я буду определять как «старше 30 минут».

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

Что мне нужно действительно нравится делать какой-то прослушиватель каталогов, который был уведомлен о любых новых файлах, добавленных в каталог. Этот слушатель затем добавит эти файлы в очередь, которая будет удалена по дороге. Однако, похоже, не существует способа реализовать такое решение на языках, на которых я программирую (языки JVM, такие как Java и Scala).

Итак: Я ищу наиболее эффективный способ сохранить каталог «как можно чище» в Windows, желательно с использованием JVM-языка. Кроме того, хотя я никогда не программировал с Powershell, я бы подумал, предложил ли он такую ​​функциональность. Наконец, если есть сторонние инструменты, чтобы делать такие вещи, я хотел бы услышать о них.

Спасибо.

ответ

4

Почему вы не можете выпустить каталог system command отсортированных по старейших первых: с:> реж/OD

Возьмите результаты и удалить все файлы старше вашего порога или сна, если файлы не достаточно стары.

Объедините это с Timer or Executor, установленным в гранулярность 1 секунда - 1 минута, что гарантирует, что файлы не будут накапливаться быстрее, чем вы можете их удалить.

+0

Спасибо, Келли. На 100 тыс. Файлов вызов listFiles() с помощью AgeFilter занял около 3 минут. Использование dir/OD, а затем синтаксический анализ результирующей строки для файлов, которые мне нужны (по времени), длится около 4 секунд. Большое улучшение! –

+0

Спасибо всем за отличные ответы. Для моего конкретного случая, находясь в Windows, комбинация использования java ProcessBuilder и правильных системных команд оказалась намного быстрее, чем использование традиционного java-подхода AgeFilter –

0

Я бы пошел с C++ для такой утилиты - позволяет вам взаимодействовать с WIN32 API, который действительно имеет возможности для прослушивания каталогов (FindFirstChangeNotification или ReadDirectoryChangesW). Используйте один поток, который прослушивает уведомления об изменениях и обновляет список файлов (iirc FFCN требует, чтобы вы повторно просматривали папку, тогда как RDCW дает вам фактические изменения).

Если вы храните этот список отсортированным в соответствии с временем модификации, становится достаточно спящий режим() достаточно долго, чтобы файл выглядел устаревшим, вместо опроса в некоторый случайный фиксированный интервал. Возможно, вы захотите сделать WaitForSingleObject с тайм-аутом вместо Sleep, чтобы реагировать на внешние изменения (т. Е. Файл, который вы ожидаете стать устаревшим, был удален извне, поэтому вы захотите проснуться и определить, когда следующий файл станет устаревшим).

Звучит как весело небольшой инструмент, чтобы написать :)

0

Вы можете стиснуть зубы и код его в C# (или VB). То, о чем вы просите, довольно хорошо обрабатывается классом FileSystemWatcher. Это будет работать в основном так, как вы описываете. Регистрируйте файлы по мере их добавления в каталог. Имейте периодический таймер, который сканирует список файлов для устаревших и удаляет их, если они все еще существуют. Вероятно, я бы назвал его службой Windows, работающей под идентификатором службы, который имеет достаточно прав для чтения/удаления файлов в каталоге.

EDIT: Быстрый поиск в google FileSystemWatcher for Java. Коммерческое программное обеспечение. Никогда не использовал его, поэтому не могу прокомментировать, насколько хорошо он работает.

2

Если вы не хотите писать C++, вы можете использовать Python.Установите pywin32, а затем вы можете использовать win32 API, как, например:

import win32api, win32con 
change_handle = win32api.FindFirstChangeNotification(
    path_to_watch, 
    0, 
    win32con.FILE_NOTIFY_CHANGE_FILE_NAME 
) 

Полное объяснение того, что делать с этой ручкой Тим Голден здесь: http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html.

2

В Java, вы можете также использовать Apache Commons JCI FAM. Это java-библиотека с открытым исходным кодом, которую вы можете использовать бесплатно.

JDK 7 (выпущен в бета-версии в настоящее время) включает также поддержку уведомлений о файлах. Выезд Java NIO2 tutorial.

Оба варианта должны работать как в Windows, так и в Linux.

+0

Отлично. WatchService - именно то, что я искал. Я думаю, что моя программа в конечном итоге будет сочетаться с 1) «Найти все старые файлы при запуске», используя предложение системной команды Kelly, а затем 2) после ее запуска он будет использовать WatchService для добавления файлов в папку, быть удаленным в очередь. –

+0

Отлично. Я рекомендую не использовать системную командную строку. используйте 'File.lastModified' и вариант того, что было рекомендовано здесь: http://stackoverflow.com/questions/1060153/search-entire-computer-for-a-file-name-in-java – notnoop

+0

msaeed, я начал с listFiles и AgeFilter, но в больших каталогах это медленная собака. Я не поклонник использования системной команды, но в моем конкретном случае это намного быстрее –

Смежные вопросы