Я пишу службу Windows в ruby с использованием гемов Win32-utils. Сервис в настоящее время работает, но большая часть его функции требует, чтобы он знал, когда файл был изменен. В настоящее время я делаю это с большим хешем, содержащим данные о каждом файле, который отлично работает для относительно небольших каталогов, но при использовании в папке, содержащей ~ 50000 файлов, это съедает много памяти и занимает много времени для проверки обновления.
Код выглядит так:
Первый запуск (настройка хэша):
Find.find(@local_base) do |path|
# Don't keep any directories in the hash
if not FileTest.directory?(path)
f = open(path)
f.rewind
@files[path.gsub(@local_base, "")] = DataFile.new(@local_base,
path.gsub(@local_base, ""),
Digest::MD5.hexdigest(f.read.gsub("\n", "\r\n")),
f.mtime.to_i,
@last_checked)
end
end
Последующие запуски (проверка обновлений):
def check_for_updates
# can't/shouldn't modified a hash while iterating, so set up temp storage
tempHash = Hash.new
Find.find(@local_base) do |path|
# Ignore directories
if not FileTest.directory?(path)
File.open(path) do |f|
#...and the file is already in the hash...
if not @files[path.gsub(@local_base, "")].nil?
# If it's been modified since the last scan...
if f.mtime.to_i > @last_checked
#...and the contents are modified...
if @files[path.gsub(@local_base, "")].modified?
#...update the hash with the new mtime and checksum
@files[path.gsub(@local_base, "")].update
end
end # mtime check
else
# If it's a new file stick it in the temporary hash
f.rewind
tempHash[f.path] = DataFile.new(@local_base,
path.gsub(@local_base, ""),
Digest::MD5.hexdigest(f.read.gsub("\n", "\r\n")),
f.mtime.to_i,
@last_scan)
end # nil check
end # File.open block
end # directory check
end # Find.find block
# If any new files are in the tempHash, add them to @files
if not tempHash.empty?
tempHash.each do |k, v|
@files[k] = v
end
end
# clear tempHash and update registry
tempHash = nil
update_last_checked
end
Существует ли более быстрый / более эффективный способ уведомления моей программы об измененных файлах, даже лучше, если я смогу сделать это без рекурсивного поиска по всему каталогу.