开发者

Traversing directories and reading from files in ruby on rails

I'm having some trouble figuring out how to 1) traverse a directory and 2) taking each file (.txt) and saving it as a string. I'm obviously pretty new to both ruby and rails.

I know that I could save the file with f=File.open("/path/*.txt") and then output it with开发者_开发技巧 puts f.read but I would rather save it as a string, not .txt, and dont know how to do this for each file.

Thanks!


You could use Dir.glob and map over the filenames to read each filename into a string using IO.read. This is some pseudo code:

file_names_with_contents = Dir.glob('/path/*.txt').inject({}){|results, file_name| result[file_name] = IO.read(file_name)}


You could prob also use tap here:

file_names_with_contents = {}.tap do |h|
  Dir.glob('/path/*.txt').each{|file_name| h[file_name] = IO.read(file_name)}
end


The following based on python os.walk function, which returns a list of tuples with: (dirname, dirs, files ). Since this is ruby, you get a list of arrays with: [dirname, dirs, files]. This should be easier to process than trying to recursively walk the directory yourself. To run the code, you'll need to provide a demo_folder.

def walk(dir)
  dir_list = []
  def _walk(dir, dir_list)
    fns = Dir.entries(dir)
    dirs = []
    files = []
    dirname = File.expand_path(dir)
    list_item = [dirname, dirs, files]
    fns.each do |fn|
      next if [".",".."].include? fn
      path_fn = File.join(dirname, fn)
      if File.directory? path_fn
        dirs << fn
        _walk(path_fn, dir_list)
      else
        files << fn
      end
    end
    dir_list << list_item
  end

  _walk(dir, dir_list)
  dir_list
end

if __FILE__ == $0

  require 'json'

  dir_list = walk('demo_folder')
  puts JSON.pretty_generate(dir_list)
end


Jake's answer is good enough, but each_with_object will make it slightly shorter. I also made it recursive.

def read_dir dir
  Dir.glob("#{dir}/*").each_with_object({}) do |f, h|
    if File.file?(f)
      h[f] = open(f).read
    elsif File.directory?(f)
      h[f] = read_dir(f)
    end
  end
end

When the directory is like:

--+ directory_a
  +----file_b
  +-+--directory_c
  | +-----file_d
  +----file_e

then

read_dir(directory_a)

willl return:

{file_b => contents_of_file_b,
 directory_c => {file_d => contents_of_file_d},
 file_e => contents_of_file_e}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜