2011-11-22 145 views
22

什麼是安全和有效的方式來刪除純Ruby中的目錄中的所有文件?我寫了空目錄(刪除所有文件)

Dir.foreach(dir_path) {|f| File.delete(f) if f != '.' && f != '..'} 

但它給了我一個No such file or directory錯誤。

謝謝。

回答

10

由於當前工作目錄不匹配dir_path - File.delete(f)僅在dir_path中給出文件的文件名,因此可能會出現此錯誤。 (我希望你在dir_path目錄下目前的工作目錄中沒有任何重要的文件名)

你需要使用File.join(dir_path, f)來構造你想要刪除的文件名。你還需要弄清楚你想如何處理目錄:

> Dir.foreach(dir_path) {|f| fn = File.join(dir_path, f); File.delete(fn) if f != '.' && f != '..'} 
Errno::EISDIR: Is a directory - /tmp/testing/blubber 
    from (irb):10:in `delete' 
    from (irb):10 
    from (irb):10:in `foreach' 
    from (irb):10 
    from :0 
+1

這工作,非常感謝!在我的情況下,dir_path目錄中不會有子目錄,因爲它用於存儲臨時文件。如果有目錄,我想如果像'!File.directory?(fn)'這樣的話就可以向內聯添加一個條件。這是對的還是我錯過了什麼? – Pablo

+0

是的,這應該做的很好 - 也讓你跳過'.'和'..'測試,因爲它們都將測試爲目錄。 – sarnold

59

FileUtils.rm_rf("#{dir_path}/.", secure: true)

+0

似乎也有效,但我認爲我更喜歡使用'Dir',因爲它是一個核心類。 – Pablo

+8

FileUtils是Ruby標準庫的一部分,因此它會自動包含在Ruby的安裝中。不管它是否是「核心」,都不是真正的問題,因爲它可以以任何方式使用,只需要'require'fileutils''就可以使用它。 –

18
FileUtils.rm_rf Dir.glob("#{dir_path}/*") if dir_path.present? 
+1

對於我來說,這種方法比最高級的方法漂亮,因爲它可以讓你使用Dir.glob的魔法。例如,如果您有嵌套的目錄,並且只想刪除其中的文件以保留目錄樹,請使用'FileUtils.rm_rf Dir.glob(「#{dir_path} /*/*.*」)''。 'Dir.glob'也會省略任何帶點前綴的文件 - 如果您想保留'.keep'文件,這非常方便。 –

+1

如果'dir_path'由於錯字或其他錯誤而爲'nil'會怎麼樣? *大多數時間ruby代碼不是以root身份運行的,對吧? – gtd

+0

@gtd感謝您的評論。是的,在這種情況下'''Dir.glob'''會返回'''/'''文件夾中的所有目錄。我認爲它不好:)如果目錄不爲空 – MyroslavN

2

現在,我喜歡在處理文件或目錄時使用Pathname類。

這應該讓你開始:

Pathname.new(dir_path).children.each { |p| p.unlink } 

unlink將刪除的目錄或文件,因此,如果你有一個嵌套的目錄要保留你要測試他們:

中移除了文件或目錄,如果self是文件,則使用File.unlink;必要時使用Dir.unlink。

+1

不起作用 – tcurdt

+0

OP說「刪除目錄中的所有文件」,並沒有提到想要刪除目錄本身。代碼刪除所有文件,不會遞歸到子目錄中,也不會刪除包含的目錄。那「幾乎是正確的」是怎麼樣的? –

+0

因爲一旦有目錄就會中斷。如果你想從字面上理解,你至少需要過濾掉目錄。 – tcurdt

3

鐵皮人幾乎做是正確的 - 但如果目錄不是空的使用

Pathname.new(dir_path).children.each { |p| p.rmtree } 
2

大頭釘到MyroslavN,如果你想與路徑名(像Rails.root做,如果它是一個Rails應用程序),你想這樣的:

FileUtils.rm_rf Dir.glob(Rails.root.join('foo', 'bar', '*')) 

我張貼這是因爲我做了他的答案不好copypaste,我意外地結束了,在我的道路額外的斜線:

Rails.root.join('foo', 'bar', '/*') 

由於它將其視爲根路徑,因此計算結果爲/*。如果你把它放在FileUtils.rm_rf Dir.glob裏,它會試圖遞歸刪除文件系統中的所有內容(可能會受到你的權限的限制)。

-1
Dir.foreach(dir_path) {|f| File.delete("#{dir_path}/#{f}") if f != '.' && f != '..'} 
+0

歡迎阿里堆棧溢出。請看看 - http://stackoverflow.com/help/how-to-answer。最好給代碼回答一些上下文,用一些文字來解釋它。另外要格式化一個代碼片段,在代碼中使用單引號。 – micstr

相關問題