web-dev-qa-db-fra.com

Comment créer un répertoire s'il n'en existe pas à l'aide de 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’ya pas de répertoire appelé somedir ou some_subdir ou les deux dans le chemin, je le veux pour le créer automatiquement.

Comment puis je faire ça?

104
marcamillion

Vous pouvez utiliser FileUtils pour créer de manière récursive 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 roue, 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
129
Eureka

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

require 'fileutils'

FileUtils.mkdir_p 'dir_name'

D'après Eureka/ commentaire .

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

D'après les 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 a fonctionné comme un charme!

4
skplunkerin

Dans le même ordre d'idées (et selon votre structure), voici comment nous avons résolu l'emplacement de stockage des captures d'écran:

Dans notre configuration 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 crochets.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?
1
Shell Bryson

La solution de "bibliothèque principale" de la réponse principale était incomplète. Si vous souhaitez utiliser uniquement les bibliothèques principales, 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 la dépendance de FileUtils empêchait le déploiement de mon application Rails sur Amazon Web Services, car rmagick dépendait du package libmagickwand-dev (Ubuntu)/imagemagick (OSX) pour fonctionner correctement.

1
CopyLeft

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)
0
ironsand