Следите за измененными файлами в Windows в Ruby - PullRequest
3 голосов
/ 08 июня 2011

Я пишу службу 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

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

Ответы [ 2 ]

1 голос
/ 09 июня 2011

Вы можете оставить это для Windows, чтобы предупредить вас, если журнал изменений изменен. Существует драгоценный камень , который "слушает" службу.

0 голосов
/ 09 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...