Comment créer un répertoire s’il n’en existe pas en utilisant la classe File dans Ruby?

J’ai cette déclaration:

File.open(some_path, 'w+') { |f| f.write(builder.to_html) } 

 some_path = "somedir/some_subdir/some-file.html" 

Ce que je veux, c’est que s’il n’y a pas de répertoire appelé somedir ou some_subdir ou les deux dans le chemin, je veux qu’il le crée automatiquement.

Comment puis je faire ça?

Vous pouvez utiliser FileUtils pour créer récursivement des répertoires parents, s’ils ne sont pas déjà présents:

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

Edit: Voici une solution utilisant uniquement les librairies principales (réimplémentation de la molette, non recommandé)

 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 

Pour ceux qui cherchent un moyen de créer un répertoire s’il n’existe pas , voici la solution simple:

 require 'fileutils' FileUtils.mkdir_p 'dir_name' 

Basé sur le commentaire d’Eureka.

 directory_name = "name" Dir.mkdir(directory_name) unless File.exists?(directory_name) 

Sur la base des réponses des autres, rien ne s’est passé (n’a pas fonctionné). Il n’y avait pas d’erreur et aucun répertoire créé.

Voici ce que je devais faire:

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

Je devais créer une variable pour attraper la réponse que FileUtils.mkdir_p('dir_name') renvoie … alors tout fonctionnait comme un charme!

Dans le même ordre d’idées (et selon votre structure), voici comment nous avons résolu où stocker les captures d’écran:

Dans notre env env (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 

Et dans nos hooks.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? 

La seule solution de la bibliothèque principale de la réponse supérieure était incomplète. Si vous souhaitez utiliser uniquement les bibliothèques de base, utilisez ce qui suit:

 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 

J'avais besoin de cette solution car le gem de dépendance de FileUtils rmagick empêchait mon application Rails de se déployer sur Amazon Web Services car rmagick dépend du paquet libmagickwand-dev (Ubuntu) / imagemagick (OSX) pour fonctionner correctement.

Que diriez-vous d’utiliser Pathname ?

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