2012-09-27 3 views

Antwort

107

Sie können FileUtils verwenden, um rekursiv übergeordnete Verzeichnisse zu erstellen, wenn sie nicht bereits vorhanden sind:

require 'fileutils' 

dirname = File.dirname(some_path) 
unless File.directory?(dirname) 
    FileUtils.mkdir_p(dirname) 
end 

Edit: Hier ist eine Lösung nur die Kernbibliotheken (das Rad neu implementieren, nicht empfohlen)

dirname = File.dirname(some_path) 
tokens = dirname.split(/[\/\\]/) # don't forget the backslash for Windows! And to escape both "\" and "/" 

1.upto(tokens.size) do |n| 
    dir = tokens[0...n] 
    Dir.mkdir(dir) unless Dir.exist?(dir) 
end 
+4

FileUtils ** ist ** in der stdlib: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html – Eureka

+0

Oh ok. Ich meinte den Kern, nicht die stdlib. Wie auch immer, das ist in Ordnung. Das funktioniert. Vielen Dank! – marcamillion

+1

Ich habe meiner Antwort eine Core-only-Lösung hinzugefügt: Beachten Sie jedoch, dass sie 'FileUtils.mkdir_p' (die Methode, die Ihrem Anwendungsfall gewidmet ist) im Wesentlichen neu implementiert. – Eureka

54

für die Suche nach einem Weg, um ein Verzeichnis erstellen, wenn es nicht existiert, hier ist die einfache Lösung:

require 'fileutils' 

FileUtils.mkdir_p 'dir_name' 

Basierend auf Eureka's comment.

1

In einer ähnlichen Richtung (und je nach Struktur), das ist, wie wir gelöst, wo Screenshots speichern:

In unserem env-Setup (env.rb)

screenshotfolder = "./screenshots/#{Time.new.strftime("%Y%m%d%H%M%S")}" 
unless File.directory?(screenshotfolder) 
    FileUtils.mkdir_p(screenshotfolder) 
end 
Before do 
    @screenshotfolder = screenshotfolder 
    ... 
end 

Und in unserem Haken. rb

screenshotName = "#{@screenshotfolder}/failed-#{scenario_object.title.gsub(/\s+/,"_")}-#{Time.new.strftime("%Y%m%d%H%M%S")}_screenshot.png"; 
    @browser.take_screenshot(screenshotName) if scenario.failed? 

    embed(screenshotName, "image/png", "SCREENSHOT") if scenario.failed? 
15
directory_name = "name" 
Dir.mkdir(directory_name) unless File.exists?(directory_name) 
+0

Sie können Race-Bedingungen mit dieser Methode auftreten, das Verzeichnis könnte nach File.exists erstellt werden? läuft aber bevor Dir.mkdir ausgeführt wird. –

3

Basierend auf andere Antworten, passiert nichts (nicht funktioniert). Es gab keinen Fehler und kein Verzeichnis erstellt.

Hier ist, was ich tun musste:

require 'fileutils' 
response = FileUtils.mkdir_p('dir_name') 

ich eine Variable zu schaffen, um die Antwort zu fangen, dass FileUtils.mkdir_p('dir_name') sendet ... dann funktionierte alles wie am Schnürchen!

+0

macht keinen Sinn. warum müssen Sie die Rückkehr abfangen? –

+0

@huanson, ich musste nicht die Rückkehr abfangen ... aber die Logik hat nicht funktioniert, bis ich 'response = FileUtils.mkdir_p ('dir_name')' erstellt habe. Wenn ich diese Variable nicht erstellt habe, funktionierte 'FileUtils.mkdir_p ('dir_name')' nicht für mich ... oder zumindest erinnere ich mich daran (diese Antwort ist mehr als 1 Jahr alt). Ich wäre nicht überrascht, wenn eine neuere Version von Ruby dieses Problem behebt. – skplunkerin

1

Die einzige Lösung der "Kernbibliothek" der obersten Antwort war unvollständig. Wenn Sie nur wollen Core-Bibliotheken verwenden, verwenden Sie die folgenden Schritte aus:

target_dir = "" 

Dir.glob("/#{File.join("**", "path/to/parent_of_some_dir")}") do |folder| 
    target_dir = "#{File.expand_path(folder)}/somedir/some_subdir/" 
end 

# Splits name into pieces 
tokens = target_dir.split(/\//) 

# Start at '/' 
new_dir = '/' 

# Iterate over array of directory names 
1.upto(tokens.size - 1) do |n| 

    # Builds directory path one folder at a time from top to bottom 
    unless n == (tokens.size - 1) 
    new_dir << "#{tokens[n].to_s}/" # All folders except innermost folder 
    else 
    new_dir << "#{tokens[n].to_s}" # Innermost folder 
    end 

    # Creates directory as long as it doesn't already exist 
    Dir.mkdir(new_dir) unless Dir.exist?(new_dir) 
end 

ich diese Lösung benötigt, da FileUtils' Abhängigkeit gem RMagick von der Bereitstellung auf Amazon Web Services meine Rails-Anwendung verhindert, da RMagick auf dem Paket libmagickwand-dev hängt ab von (Ubuntu)/imagemagick (OSX) um richtig zu funktionieren.

0

Wie wäre es mit Pathname?

require 'pathname' 
some_path = Pathname("somedir/some_subdir/some-file.html") 
some_path.dirname.mkdir_p 
some_path.write(builder.to_html) 
Verwandte Themen