File类与Dir类

File类

更改文件名

File.rename(before, after)

File.rename ("before.txt", "after.txt")

复制文件

使用File.open和File.write

def copy(from, to)
  File.open(from) do |input|
    File.open(to, "w") do |output|
      output.write(input.read)
    end
  end
end

copy "hello.txt", "ruby.txt"

使用fileutils库

require "fileutils"

FileUtils.cp("data.txt", "backup/data.txt")
FileUtils.mv("data.txt", "backup/data.txt")

删除文件

File.delete(file) File.unlink(file)

File.delete("data.txt")

目录操作

Dir.pwd Dir.chdir(dir)

p Dir.pwd                   #=> "/usr/local/lib"
Dir.chdir("ruby/2.0.0")     #=> 根据相对路径移动

p Dir.pwd
Dir.chdir("/etc")

p Dir.pwd

目录的读取

  • 打开目录
  • 读取内容
  • 关闭

Dir.open(path) Dir.close

dir = Dir.open("/usr/bin")
while name = dir.read
    p name
end

dir.close
dir = Dir.open("/usr/bin")
dir.each do |name|
    p name
end

#注意关闭
dir.close
Dir.open("/usr/bin") do |dir|
    dir.each do |name|
        p name
    end
end

#用块就不需要close了

dir.read

def traverse(path)
  if File.directory?(path)
    dir = Dir.open(path)
    while name = dir.read
      next if name == "."
      next if name == ".."
      traverse(path + "/" + name)
    end
    dir.close
  else
    process_file(path)
  end
end

def process_file(path)
  puts path
end

traverse "/Users/Aaron"

Dir.glob

使用通配符来取得文件名

方法名 意义
Dir.glob("*") 获取当前目录中所有的文件名(不含.开头的)
Dir.glob(".*") 获取当前目录中所有隐藏文件名
Dir.glob(["*.html", "*.htm"]) 获取扩展名为.html或.htm的文件名。通过数组指定
Dir.glob("%w(*.html *htm)") 同上,%w转为数组
Dir.glob(["*/*.html", "*/*.htm"]) 获取子目录下扩展名为.html或.htm的文件
Dir.glob("foo.[cho]") 获取文件名为foo.c、foo.h、foo.o的文件
Dir.glob("**/*") 获取当前目录及子目录中所有的文件名,递归查找目录
Dir.glob("foo/**/*.html") 获取目录foo及其子目录中所有扩展名为.html的文件名,递归查找目录

使用glob代替上面的递归

def traverse(path)

  Dir.glob(["#{path}/**/*", "#{path}/**/.*"]).each do |name|
    unless File.directory?(name)
      p name
    end
  end
end

traverse "/Users/Aaron/Music"

目录的创建于删除

Dir.mkdir(path)

用于创建新目录

Dir.mkdir("temp")

Dir.rmdir(path)

用于删除空目录

Dir.rmdir("temp")

文件与目录的属性

File.stat(path)

方法 返回值的含义
dev 文件系统的编号
ino i-node编号
mode 文件的属性
nlink 链接数
uid 文件所有者的用户ID
gid 文件所属组的组ID
rdev 文件系统的驱动器种类
size 文件大小
blksize 文件系统的块大小
blocks 文件占用的块数量
atime 文件的最后访问时间 (Time对象)
mtime 文件的最后修改时间 (Time对象)
ctime 文件状态的最后更改时间 (Time对象)

File.ctime(path) File.mtime(path) File.atime(path)

与File::stat#ctime、File::stat#mtime、File::stat#atime一样

File.utime(atime, mtime, path)

改变文件属性中的最后访问时间atime、最后修改时间mtime。可以使用证书或者Time对象

filename = "foo"
#创建文件后关闭
File.open(filename, "w").close

st = File.stat(filename)
p st.ctime      #=> 2016-02-18 23:53:45 +0800
p st.mtime      #=> 2016-02-18 23:53:45 +0800
p st.atime      #=> 2016-02-18 23:53:45 +0800

File.utime(Time.now-100, Time.now-100, filename)
st = File.stat(filename)
p st.ctime      #=> 2016-02-18 23:53:45 +0800
p st.mtime      #=> 2016-02-18 23:52:05 +0800
p st.atime      #=> 2016-02-18 23:52:05 +0800

File.chomd(mode, path)

修改文件的访问权限

111(所有者) 111(所有组) 111(其他用户)

File.chomd(0755, ""test.txt")

File.chown(owner, group, path)

改变文件的所有者

FileTest模块

用于检查文件的属性。可以include后使用,也可以直接作为模块函数调用。

方法 返回值
exist?(path) path存在返回true
file?(path) path若是文件返回true
directory?(path) path若是目录返回true
owned?(path) path的所有者于执行用户一样返回true
grpowned?(path) path的所属组于执行用户所属组一样返回true
readable?(path) path可读返回true
writable?(path) path可写返回true
executable?(path) path可执行返回true
size(path) 返回path大小
size?(path) path大于0返回true,为0或不存在返回nil
zero?(path) path的大小为0返回true

文件名操作

File.basename(path[, suffix])

返回路径path中最后一个"/"以后的部分。如果指定了扩展名suffix,则会去除返回值中扩展名部分。

p File.basename("/usr/local/bin/ruby")      #=> "ruby"
p File.basename("/src/ruby/file.c", ".c")   #=> "file"
p File.basename("file.c")      #=> "file"

File.dirname(path)

p File.dirname("/usr/local/bin/ruby")       #=> "/usr/local/bin"
p File.dirname("ruby")      #=> "."
p FIle.dirname("/")         #=> "/"

File.extname(path)

p File.extname("hello.rb")      #=> "rb"
p File.extname("~/.zhsrc")      #=> ""

File.split(path)

将路径分割为目录名与文件名两部分,并以数组返回

p File.split("/usr/local/bin/ruby")
#=> ["/usr/local/bin", "ruby"]

dir, base = File.split("/usr/local/bin/ruby")

File.join(name1[, nam2, ...])

用File::SEPARATOR(默认/)链接参数指定的字符串。

p File.join("/usr/bin", "ruby")     #=> "/usr/bin/ruby"

File.extend_path

根据目录名default_dir,将相对路径path转为绝对路径。不指定default_dir,则根据当前目录。

p Dir.pwd                       #=> "/usr/local"
p File.extend_path("bin")       #=> "/usr/local/bin"
p File.extend_path("../bin")    #=> "/usr/bin"
p File.extend_path("bin", "/usr")   #=> "/usr/bin"
p File.extend_path("~/bin")     #=> "/home/Aaron/bin"

与文件操作相关的库

Find库

Find.find(dir){|path|...} Find.prune

Find.find会将目录dir下所有文件路径逐个传个path。使用Find.prune跳过当前目录,用next只能跳过当前目录,子目录还是被查找。

require 'find'
IGNORES = [ /^\./, /^CVS$/, /^RCS$/ ]

def listdir(top)
  Find.find(top) do path
    if FileTest.directory?(path)
      dir, base = File.split(path)
      IGNORES.each do |re|
        if re =~ path
          File.prune
        end
      end
      puts path
    end
  end
end

listdir(ARGV[0])

tempfile库

管理临时文件

方法名 意义
Tempfile.new(basename[, tempdir]) 创建临时文件
Tempfile.close(real) 删除临时文件
Tempfile.open 再次打开close方法关闭的临时文件
Tempfile.path 返回临时文件的路径

fileutils库

需要require

方法名 意义
FileUtils.cp(from, to) 复制文件。from可以指定数组,to则指定为目录,一次性复制多个文件
FileUtils.cp_r(from, to) 同上,from为目录时,进行递归拷贝
FileUtils.mv(from, to) 移动
FileUtils.rm(path) FileUtils.rm_f(path) 删除文件,可以指定数组。异常会中断执行,第二个方法忽略错误。
FileUtils.rm_r(path) FileUtils.rm_rf(path) 删除目录,可以指定数组。
FileUtils.compara(from, to) 比较文件,相同返回true
FileUtils.install(from, to[, option] 把文件从from拷贝到to,如果文件已经存在,且与form内容一致,则不拷贝 FileUtils.install(from, to, :mode=>0755)
FileUtils.mkdir_p(path) 递归创建目录 FileUtils.mkdir_p("foo/bar/baz")