首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Ruby 遞迴走訪目錄的多種寫法:從基本遞迴到 Find 模組與優雅單行版

     編輯:更多程式設計知識

Ruby 提供多種走訪目錄樹的方式。本文收集四種具代表性的寫法:手寫遞迴函式、Dir.entries 迭代、Python 對照版、以及最推薦的 Find.find / Dir.glob 優雅寫法,幫助你根據專案需求選擇最適合的方案。

寫法一:手寫遞迴函式(教學用)


def traverse_dir(file_path)
  if File.directory?(file_path)
    Dir.foreach(file_path) do |file|
      next if file == '.' || file == '..'
      traverse_dir(File.join(file_path, file))
    end
  else
    puts "File: #{File.basename(file_path)}, Size: #{File.size(file_path)}"
  end
end

traverse_dir('D:/apache-tomcat')
  • 優點:邏輯清晰,適合理解遞迴原理。
  • 缺點:手動處理 ./..、路徑拼接、錯誤處理,程式碼冗長。

寫法二:Dir.entries 迭代(稍簡化)


def get_file_list(path)
  Dir.entries(path).each do |sub|
    next if sub == '.' || sub == '..'
    full = File.join(path, sub)
    if File.directory?(full)
      puts "[#{sub}]"
      get_file_list(full)
    else
      puts " |--#{sub}"
    end
  end
end

寫法三:Python 版對照(跨語言參考)


import os
def get_file_list(dir, file_list):
    if os.path.isfile(dir):
        file_list.append(dir)
    elif os.path.isdir(dir):
        for s in os.listdir(dir):
            get_file_list(os.path.join(dir, s), file_list)
    return file_list

for f in get_file_list('D:/workspace', []):
    print f

寫法四:Find.find / Dir.glob(推薦,生產級)

Find.find 遞迴走訪


require 'find'
Find.find('/home/bruce') do |path|
  puts path if File.file?(path)
end
  • 自動處理 ./..、路徑拼接、權限錯誤。
  • Find.prune 可跳過特定目錄遞迴。

Dir.glob 模式匹配(最簡潔)


# 所有檔案遞迴
Dir.glob("**/*", File::FNM_DOTMATCH).each { |f| puts f if File.file?(f) }

# 特定副檔名
Dir.glob("**/*.rb").each { |f| puts f }

# 遞迴迭代器(記憶體效率佳)
Dir.glob("**/*") do |f|
  puts f if File.file?(f)
end

進階:自訂迭代器(類 Python os.walk)


def iter_browse(path)
  return enum_for(:iter_browse, path) unless block_given?
  Find.find(path) do |f|
    yield f if File.file?(f)
  end
end

iter_browse("/home/bruce") { |full| puts full }
# 或
iter_browse("/home/bruce").each { |f| puts f }

效能與選擇建議

方法記憶體速度適用場景
手寫遞迴O(深度)慢教學、特殊邏輯控制
Dir.entries + 遞迴O(深度)中簡單腳本
Find.findO(深度)快標準遞迴走訪、需 prune
Dir.glob("**/*")O(檔案數)快模式匹配、一次性列表
Dir.glob 區塊形式O(1) 流式快大量檔案、記憶體敏感

常見陷阱

  • 符號連結循環:Find.find 不會自動偵測 symlink 循環,需自行維護 visited 集合。
  • 權限錯誤:無讀取權限目錄會拋例外,需 rescue Errno::EACCES。
  • 編碼問題:Windows 檔名編碼可能非 UTF-8,Ruby 2.0+ 處理較好,舊版需 Encoding.default_external。

總結

日常腳本首選 Dir.glob("**/*.ext") 或 Find.find 區塊形式,簡潔、高效、記憶體友善。手寫遞迴僅用於教學或極特殊邏輯需求。理解 Find.prune、FNM_DOTMATCH、區塊與枚舉器的差異,能靈活應對各類目錄走訪任務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved