Я обрабатываю файлы и каталоги, которые ищут самый последний измененный файл в каждом каталоге. Код, который у меня есть, но, будучи новым для Ruby, я неправильно исправляю ошибки.Как обрабатывать исключения в Find.find
Я использую Find.find
получить рекурсивный список каталогов, называя свою собственную функцию newestFile
для каждого каталога:
Find.find(ARGV[0]) { |f|
if File.directory?(f)
newestFile(f)
end
}
В дереве каталогов есть папки у меня нет разрешения на доступ, поэтому я хочу, чтобы игнорировать их и перейти к следующему, но я не вижу, как включить обработку исключений в цикл «Find.find
».
Я попытался поместить begin..rescue..end
вокруг блока, но это не позволяет мне продолжить обработку цикла.
Я также нашел этот вопрос: How to continue processing a block in Ruby after an exception?, но который обрабатывает ошибку в петля. Я пытаюсь восстановить из ошибок, возникающих в Find.find
, которые будут вне блока исключений.
Вот трассировки стека ошибки:
PS D:\dev\ruby\> ruby .\findrecent.rb "M:/main/*"
C:/Ruby200/lib/ruby/2.0.0/find.rb:51:in `open': Invalid argument - M:/main/<A FOLDER I CAN'T ACCESS> (Errno::EINVAL)
from C:/Ruby200/lib/ruby/2.0.0/find.rb:51:in `entries'
from C:/Ruby200/lib/ruby/2.0.0/find.rb:51:in `block in find'
from C:/Ruby200/lib/ruby/2.0.0/find.rb:42:in `catch'
from C:/Ruby200/lib/ruby/2.0.0/find.rb:42:in `find'
from ./findrecent.rb:17:in `<main>'
Как добавить обработку исключений в этом коде?
Я заглянула в коде, где исключение генерируется и способ содержит следующий блок:
if s.directory? then
begin
fs = Dir.entries(file)
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
next
end
... more code
Выполнение ужасный хак я добавил Errno::EINVAL
к списку rescue
ошибок. Мой код теперь выполняется и проходит через все папки, но я не могу оставить это изменение в коде библиотеки Ruby.
Внутренне find
использует Dir.entries
, поэтому, возможно, мне нужно переписать код для обработки в другие папки самостоятельно, а не полагаться на find
.
Я все еще хотел бы знать, есть ли способ обработки ошибок в такой конструкции кода, как от чтения другого кода. Этот тип мелкого/сжатого кода используется много в Ruby.
Я обновил свой вопрос с помощью трассировки стека. К сожалению, ошибка возникает в коде 'Find.find'. – Tony
Спасибо за ваши предложения. Ваш комментарий: «Это должно произойти внутри этого метода». заставило меня подумать о дальнейшем расследовании, поэтому я посмотрел код 'find', и я добавил больше к моему вопросу. – Tony
Ruby 'Find' специально написан для той цели, к которой использует OP, для быстрого пересечения иерархии каталогов и выборочной обработки файлов или каталогов на основе критериев. 'Dir.entries' более общий и * может * использоваться аналогичным образом, но приведет к большему количеству кода. –