gpt4 book ai didi

ruby - 如何处理 Find.find 中的异常

转载 作者:可可西里 更新时间:2023-11-01 11:28:35 25 4
gpt4 key购买 nike

我正在处理文件和目录,以在每个目录中查找最近修改的文件。我的代码可以工作,但作为 Ruby 的新手,我无法正确处理错误。

我使用 Find.find 获取递归目录列表,为每个目录调用我自己的函数 newestFile:

Find.find(ARGV[0]) { |f| 
if File.directory?(f)
newestFile(f)
end
}

在目录树中有我无权访问的文件夹,所以我想忽略它们并继续下一步,但我看不到如何将异常处理合并到 Find.find “循环”。

我试图将 begin..rescue..end 放在 block 周围,但这不允许我继续处理循环。

我还发现了这个 SO 问题:How to continue processing a block in Ruby after an exception?但这处理了循环中的错误。我正在尝试从 Find.find 中发生的错误中恢复,该错误将在异常 block 之外。

这是错误的堆栈跟踪:

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>'

如何向这段代码添加异常处理?

我查看了生成异常的代码,该方法包含以下 block :

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 中被大量使用。

最佳答案

您是否在 newestFile 函数或尝试运行 File#directory? 时遇到此错误?

如果这发生在 newestFile 中,您可以这样做:

Find.find(ARGV[0]) do |f| 
if File.directory?(f)
newestFile(f) rescue nil
end
end

这只是忽略任何错误,直到下一个文件夹。如果需要,您还可以做一些更好的输出:

Find.find(ARGV[0]) do |f| 
if File.directory?(f)
begin
newestFile(f)
rescue
puts "error accessing: #{f}, you might now have permissions"
end
end
end

如果错误发生在 File#directory? 中,您还需要包装该部分:

Find.find(ARGV[0]) do |f|
begin
if File.directory?(f)
newestFile(f)
end
rescue
puts "error accessing: #{f}, you might now have permissions"
end
end

就像您提到的那样,如果错误发生在 Find#find 本身,那么您就无法从 block 中捕获它。它必须在该方法内部发生。

您能否通过粘贴异常的堆栈跟踪来确认异常发生在该方法中而不是后续方法中?

编辑

我打算建议您自己使用 Dir#entries 之类的东西遍历目录,这样您就可以有能力捕获错误。我感兴趣的一件事是,如果您在命令行调用中离开 *。我在 MacOS 上,所以我无法 100% 复制您所看到的内容,但是如果我允许它遍历我在我的 Mac 上无权访问的目录,它会打印有关我无法访问的文件夹的调试信息,但会继续在。如果我给它另一个 * 它似乎除了打印它无法访问的第一个文件夹的错误之外什么都不做。

我在 MacOS 上的体验的一个不同是它实际上并没有抛出异常,它只是将调试信息打印到控制台。但有趣的是,如果我无权访问文件夹,包含 * 会使我的完全停止。

关于ruby - 如何处理 Find.find 中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26805205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com