第16章 File类与Dir类
File.rename |
① 更改文件名 ② 将文件移动到其他现有目录下。若目录不存在,则会发生错误。此外,移动时无法跨越文件系统或磁盘驱动器。 |
File.rename(“before.txt”, “after.txt”) File.rename(“data.txt”, “backup/data.txt”) |
|
def copy(from, to) open(from) {|input| open(to, “w”){|output| output.write(input.read) } } end |
文件复制需自定义,或者加上一行 “require fileutils“,就可以使用FileUtils.cp、FileUtil.mv等各种用来操作文件的方法。 FileUtil.mv方法可跨文件系统或磁盘驱动器移动文件。 |
require “fileutils” FileUtils.cp(“data.txt”, “backup/data.txt”) FileUtils,mv(“data.txt”, “backup/data1.txt”) |
|
File.delete File.unlink |
删除文件 |
|
|
目录的操作
在Windows的命令提示符下,目录的分隔字符是“\”。但“\”代表转义字符,写在程序里很不方便,另外也无法在UNIX下运行,所以Ruby也支持在Windows下使用“/”作为分隔字符。
获取当前目录: Dir.pwd |
|
更改当前目录: Dir.chdir Dir.chdir方法的实参可以指定从当前目录算起的相对路径,也可以指定从 根目录算起的绝对路径。 |
p Dir.pwd #=> “/usr/local/lib/ruby/1.8” io.open(“find.rb”) io.close Dir.chdir(“../..”) #=> 移动到两层之前的目录 p Dir.pwd #=> 移动到两层之前的目录 io.open(“ruby/1.8/find.rb”) io.close Dir.chdir(“/etc”) #=> 以绝对路径移动 p Dir.pwd #=> “/etc” |
读取目录操作
dir = Dir.open(“/usr/bin”) while name = dir.read p name end dir.close |
dir = Dir.open(“/usr/bi”){|dir| dir.each{|name| p name } } |
Dir.open与File.open一样,使用语句块打开时,就可以省略调用close方法。这是,语句块内的参数是新建立的Dir对象。
执行Dir#read方法时,目录中的内容会依序逐个读出。这里可能读出的内容有下面4种:
l 代表当前目录的“.”
l 代表上层目录的“..”
l 其他下层目录名;
l 文件名
因此,“/usr/bin”与“usr/bin/.”所指的是同一个文件。
建立目录与删除目录
建立目录 |
Dir.mkdir(“temp”) |
删除目录 |
Dir.rmdir(“temp”) |
文件与目录的属性
使用File.stat方法,可以获取文件或目录的属性。File.stat方法的返回值会是File::Stat类的实例。
File::Stat类的实例方法
方法 |
返回值的意义 |
方法 |
返回值的意义 |
Dev |
文件系统的装置代号 |
uid |
文件所有者ID |
Ino |
i-node编号 |
gid |
文件所有群组ID |
mode |
文件属性 |
redv |
文件系统的装置类型 |
nlink |
连接数量 |
size |
文件大小 |
blksize |
文件系统的区块大小 |
blocks |
文件占用的区块数 |
atime |
文件最后访问时间 |
mtime |
文件最后修改时间 |
ctime |
文件状态最后变更时间 |
|
|
其中,除了atime方法、mtime方法、ctime方法返回Time对象以外,其他方法返回的都是整数。
require ‘etc’ include Etc st = File.stat(“/usr/local/bin/ruby”) pw = getpwuid(st.uid) p pw.name #=> “root” gr = getgrgid(st.gid) p gr.name #=> “wheel” |
要从uid方法、gid方法所返回的整数中获取其对应的使用者名称与群组名称时,可以使用Etc模块。使用Etc模块时,应加上一行“require ‘etc’”。
mswin32版的Ruby不能使用Etc模块。 |
File.utime(atime, mtime, path) 修改文件path的最后访问时间atime与最后修改时间mtime。时间可以指定为整数值或Time对象。也可以同时指定不只一个路径名。 |
filename = “foo” open(filename, “w”).close st=File.stat(filename) p st.ctime #=> Sat Nov 11 19:10:22 +0800 2006 p st.mtime #=> Sat Nov 11 19:14:05 +0800 2006 p st.atime #=> Sat Nov 11 19:14:05 +0800 2006
File.utime(Time.now-100, Time.now-100, filename) st = File.stat(filename) p st.ctime #=> Sat Nov 11 19:10:22 +0800 2006 p st.mtime #=> Sat Nov 11 19:12:25 +0800 2006 p st.atime #=> Sat Nov 11 19:12:25 +0800 2006 |
File.chmod(mode, path)
更改文件path的访问权限。mode应以整数值指定,同时可以指定不只一个文件路径。
* Windows文件的执行权限是由扩展名(.bat或.exe等)决定的,无法以这个方法更改。
访问权限是表示执行、写入、读取3种行为权限的3位整数值。而它又可以分别针对所有者、所有群组、其他人设定访问权限,所以总共以9个位表示。依次为:文件所有者的许可模式(读取、写入、执行)、文件所有群组的许可模式、其他人的许可模式。
因为八进制刚好以一个数字表示3个位,所以文件权限一般习惯使用八进制来写。
File.chmod(0755, “test.txt”) |
将文件test.txt的许可权限设定成0755(文件所有者可做任何操作,其他人只能读取与执行) |
rb_file = “rest.rb” st = File.stat(rb_file) File.chmod(st.mode | 0111, rb_file) # 加上执行权限 |
只想要加上特定位时,则应使用File.stat方法获取现在的权限以后,加上指定位再设定回去。要加上位,应使用位和运算。 |
File.chown(owner, group, path) |
更改文件path的所有者,同时可指定多个文件。执行这个方法时必须具有系统管理员权限。 |
FileTest模块
FileTest模块用来检查文件的属性。使用时可以读入使用,也可以当作模块函数来使用。
方法 |
返回值 |
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时或文件不存在时返回false |
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”
|
File.dirname(path) 从路径中获取目录的部分 从path中获取前端到最后一个“/”为止的部分。当路径中没有“/”字符时,会返回“.”。 |
p File.dirname(“/ usr/local/bin/ruby”) #=> “/usr/local/bin” p File.dirname(“ruby”) #=> “.” p File.dirname(“/”) #=> “/” |
File.extname(path) 从path中获取basename方法所取得的文件名部分中的扩展名部分。没有扩展名或文件名以“.”开始时,返回空字符串。 |
p File.extname(“helloruby.rb”) #=> “.rb” p File.extname(“ruby-1.8.5.tar.gz”) #=> “.gz” p File.extname(“/usr/local/bin/ruby”) #=> “” p File.extname(“~/.zshrc”) #=> “” |
File.split(path) 将path分解成目录名与文件名两部分,返回一个具有两个元素的数组。 |
p File.split(“/usr/local/bin/ruby”) #=> [“/usr/local/bin”, “ruby”] p File.split(“ruby”) #=> [“.”, “ruby”] p File.split(“/”) #=> [“/”, “”] |
File.join(dir, base) File.split的反向操作 |
p File.join(“/usr/local/bin”, “ruby”) #=> “/usr/local/bin/ruby” p File.join(“.”, “ruby”) #=> “./ruby” |
File.expand_path(path [, default_dir]) |
p Dir.pwd #=> “/usr/local” p File.expand_path(“bin”) #=> “/usr/local/bin” p File.expand_path(“../bin”) #=> “/usr/bin” p File.expand_path(“bin”, “/usr”) #=> “/usr/bin” p File.expand_path(“../etc”, “/usr”) #=> “/etc” |
在UNIX环境下,使用“~使用者名称”可以获取使用者的主目录。另外,”~/”则代表现在执行程序的使用者的主目录。
p File.expand_path(“~ /bin”) #=> “/home/susan/bin” p File.expand_path(“~helen/bin”) #=> “/home/helen/bin” |
与文件操作相关的程序库
- find.rb
find.rb中所提供的Find模块,能够递归处理指定目录下所游子目录中的目录或文件。
Find.find(dir){|path|…} |
将dir所指定的目录下所有路径传递给参数path进行处理 |
Find.prune |
跳过现在正在查找的目录下的所有内容。单纯地使用next时,会跳过的只有这个目录,并不会跳过这个目录的子目录。 |
示例: 显示出实参top所指定的路径以下的所有目录。若在IGNORES录入了不想查找的目录时,则使用Find.prune方法跳过这些目录不查找。
require ‘find’ IGNORES = [/^\./, /^CVS$/, /^RCS$/] def listdir(top) File.find(top) {|path| if FileTest.directory?(path) # 若path是目录 dir, base = File.split(path) # 多重赋值 IGNORES.each{|re| if re =~ base # 若是想要忽略的目录 Find.prune # 跳过这个目录不查找 end } puts path # 输出 end } end listdir(ARGV[0]) |
- tempfile.rb
tempfile.rb程序库用来管理暂存文件
tempfile.new(basename [,tempdir]) |
建立暂存文件。实际建立的文件名是basename加上进程ID与流水号的值。因此就算指定相同的basename,每次调用new方法产生出的文件也不会相同。没有指定tempdir时,会依序查找ENV[‘TEMPDIR’]、ENV[‘TMP’]、ENV[‘TEMP’]、’/tmp’,存放在最先找到的目录下。 |
tempfile.close(real) |
关闭暂存文件。当real值为true时,暂存文件会即时删除。即使不要求删除,Tempfile对象也会在GC的时候自动删除。real的默认值是false。 |
tempfile.open |
重新打开一度以close方法关闭的暂存文件 |
tempfile.path |
返回暂存文件的路径 |
- fileutils.rb
FileUtils.cp(from, to) |
将文件从from复制到to。当to时目录时,则会在to下面建立与from同名的文件。from可以使用数组指定多个文件一次性复制,这时to一定要指定目录。 |
FileUtils.cp_r(from, to) FileUtils.cp_rf(from, to) |
与FileUtils.cp方法大致相同,差异在于当from是目录时,会反复地进行复制。FileUtils.cp_r方法在复制过程中发生错误时会停止执行,而FileUtils.cp_rf方法会忽略错误继续执行。 |
FileUtils.mv(from, to) |
将文件从from移动到to。当to是目录时,则会移动到to下,文件名保留与from相同。from可以使用数组指定多个文件一次性移动,这时to一定要指定目录。 |
FileUtils.rm(path) |
删除path。path必须是文件,可以数组方式指定多个。 |
FileUtils.rm_r(path) FileUtils.rm_rf(path) |
删除path。path如果是目录,则会反复地删除目录下的所有目录和文件。FileUtils.rm_r方法在复制过程中发生错误时会停止执行,而FileUtils.rm_rf方法会忽略错误继续执行。 |
FileUtils.compare(from, to [,option]) |
比较文件from与to的内容,相同时返回true,不同时返回false。 |
FileUtils.mkdir_p(path) |
一次性建立多层目录 |
FileUtils.install(from, to [,option]) |
将文件从from复制到to。若to已经存在,内容也与from相同,则不做复制的动作。另外,选项option可以指定复制目标的文件访问权限。 |