1ruby文件操作关键字:file ruby转!1检测文件是否存在及其大小FileTest的exist?方法可以检测一个文件是否存在:Ruby代码1.flag=FileTest::exist?("LochNessMonster")2.flag=FileTest::exists?("UFO")3.#exists?is a synonym for exist?Ruby代码1.flag=FileTest::exist?("LochNessMonster")2.flag=FileTest::exists?("UFO")3.#exists?is a synonym for exist?如果我们想要知道文件是否有内容,可以使用File::Stat的zero?方法:Ruby代码1.flag=File.new("somefile").stat.zero?Ruby代码1.flag=File.new("somefile").stat.zero?这个将会返回true,这是因为在ruby中0也是true,nil才是false.所以我们可以使用size?方法:Ruby代码1.if File.new("myfile").stat.size?2.puts"The file has contents."3.else4.puts"The file is empty."5.end1.if File.new("myfile").stat.size?2.puts"The file has contents."3.else4.puts"The file is empty."5.endFileTest模块里面也有zero?和size?方法:Ruby代码1.flag1=FileTest::zero?("file1")2.flag2=FileTest::size?("file2")Ruby代码1.flag1=FileTest::zero?("file1")2.flag2=FileTest::size?("file2")这里还有一个size方法:Ruby代码1.size1=File.size("file1")2.size2=File.stat("file2").sizeRuby代码1.size1=File.size("file1")2.size2=File.stat("file2").size2检测特殊文件属性这边要注意,File类mix了FIleTest模块,并且FileTest模块和File::Stat 模块功能上也有很多重复.unix/linux有面向字符和面向块的设备。
FileTest的方法blockdev?和chardev?可以进行测试:1.flag1=FileTest::chardev?("/dev/hdisk0")#false2.flag2=FileTest::blockdev?("/dev/hdisk0")#trueRuby代码1.flag1=FileTest::chardev?("/dev/hdisk0")#false2.flag2=FileTest::blockdev?("/dev/hdisk0")#true有时我们想要知道一个流是否联系到了终端,这时我们可以使用IO类的tty?方法:Ruby代码1.flag1=STDIN.tty?#true2.flag2=File.new("diskfile").isatty#falseRuby代码1.flag1=STDIN.tty?#true2.flag2=File.new("diskfile").isatty#false一个流可以是一个管道,或者一个socket:Ruby代码1.flag1=FileTest::pipe?(myfile)2.flag2=FileTest::socket?(myfile)Ruby代码1.flag1=FileTest::pipe?(myfile)2.flag2=FileTest::socket?(myfile)要区分目录和普通文件我们这样使用:Ruby代码1.file1=File.new("/tmp")2.file2=File.new("/tmp/myfile")3.test1=file1.directory?#true4.test2=file1.file?#false5.test3=file2.directory?#false6.test4=file2.file?#trueRuby代码1.file1=File.new("/tmp")2.file2=File.new("/tmp/myfile")3.test1=file1.directory?#true4.test2=file1.file?#false5.test3=file2.directory?#false6.test4=file2.file?#trueFile还有一个类方法ftype,他将返回流的类型.他也在File::Stat里面,只不过是实例方法.它的返回值可能是下面的字符串(file、directory、blockSpecial、characterSpecial、fifo、link或socket).Ruby代码1.this_kind=File.ftype("/dev/hdisk0")#"blockSpecial"2.that_kind=File.new("/tmp").stat.ftype#"directory"Ruby代码1.this_kind=File.ftype("/dev/hdisk0")#"blockSpecial"2.that_kind=File.new("/tmp").stat.ftype#"directory"要测试一个文件是否为另一个文件的链接,可以使用FileTest的symlink?方法,要计算链接数量,可以使用nlink方法:Ruby代码1.File.symlink("yourfile","myfile")#Make a link2.is_sym=FileTest::symlink?("myfile")#true3.hard_count=File.new("myfile").stat.nlink#0Ruby代码1.File.symlink("yourfile","myfile")#Make a link2.is_sym=FileTest::symlink?("myfile")#true3.hard_count=File.new("myfile").stat.nlink#03使用管道ruby中使用IO.popen打开管道:Ruby代码1.check=IO.popen("spell","r+")2.check.puts("'T was brillig,and the slithy toves")3.check.puts("Did gyre and gimble in the wabe.")4.check.close_write5.list=check.readlines6.list.collect!{|x|x.chomp}7.#list is now%w[brillig gimble gyre slithy toves wabe]Ruby代码1.check=IO.popen("spell","r+")2.check.puts("'T was brillig,and the slithy toves")3.check.puts("Did gyre and gimble in the wabe.")4.check.close_write5.list=check.readlines6.list.collect!{|x|x.chomp}7.#list is now%w[brillig gimble gyre slithy toves wabe]要注意必须调用close_write,如果没有调用它,读取管道的时候,就不能到达文件的末尾.下面是一个block的形式:Ruby代码1.File.popen("/usr/games/fortune")do|pipe|2.quote=pipe.gets3.puts quote4.#On a clean disk,you can seek forever.-Thomas Steel5.endRuby代码1.File.popen("/usr/games/fortune")do|pipe|2.quote=pipe.gets3.puts quote4.#On a clean disk,you can seek forever.-Thomas Steel5.end如果指定了一个字符串"-",那么一个新的ruby实例将被创建.如果指定了一个block,那么这个block将会作为两个独立的进程运行。
子进程得到nil,父进程得到一个IO对象:Ruby代码1.IO.popen("-")do|mypipe|2.if mypipe3.puts"I'm the parent:pid=#{Process.pid}"4.listen=mypipe.gets5.puts listen6.else7.puts"I'm the child:pid=#{Process.pid}"8.end9.end10.11.#Prints:12.#I'm the parent:pid=1058013.#I'm the child:pid=10582Ruby代码1.IO.popen("-")do|mypipe|2.if mypipe3.puts"I'm the parent:pid=#{Process.pid}"4.listen=mypipe.gets5.puts listen6.else7.puts"I'm the child:pid=#{Process.pid}"8.end9.end10.11.#Prints:12.#I'm the parent:pid=1058013.#I'm the child:pid=10582pipe方法也返回互相连接的一对管道:Ruby代码1.pipe=IO.pipe2.reader=pipe[0]3.writer=pipe[1]4.5.str=nil6.thread1=Thread.new(reader,writer)do|reader,writer|7.#writer.close_write8.str=reader.gets9.reader.close10.end11.12.thread2=Thread.new(reader,writer)do|reader,writer|13.#reader.close_read14.writer.puts("What hath God wrought?")15.writer.close16.end17.18.thread1.join19.thread2.join20.21.puts str#What hath God wrought?Ruby代码1.pipe=IO.pipe2.reader=pipe[0]3.writer=pipe[1]4.5.str=nil6.thread1=Thread.new(reader,writer)do|reader,writer|7.#writer.close_write8.str=reader.gets9.reader.close10.end11.12.thread2=Thread.new(reader,writer)do|reader,writer|13.#reader.close_read14.writer.puts("What hath God wrought?")15.writer.close16.end17.18.thread1.join19.thread2.join20.21.puts str#What hath God wrought?4使用非阻塞IOruby会在后台执行一些操作,使io不会被阻断,因此大部分情况下可以使用ruby 线程来管理IO,当一个线程被Io阻塞之后,另外的线程能够继续执行.由于ruby的线程不是一个native的线程,因此ruby的线程都在同一个进程里面.如果你想关闭一个非阻塞io,你可以这样做:Ruby代码1.require'io/nonblock'2.3.#...4.5.test=mysock.nonblock?#false6.7.mysock.nonblock=true#turn off blocking8.#...9.mysock.nonblock=false#turn on again10.11.mysock.nonblock{some_operation(mysock)}12.#Perform some_operation with nonblocking set to true13.14.mysock.nonblock(false){other_operation(mysock)}15.#Perform other_operation with non-blocking set to falseRuby代码1.require'io/nonblock'2.3.#...4.5.test=mysock.nonblock?#false6.7.mysock.nonblock=true#turn off blocking8.#...9.mysock.nonblock=false#turn on again10.11.mysock.nonblock{some_operation(mysock)}12.#Perform some_operation with nonblocking set to true13.14.mysock.nonblock(false){other_operation(mysock)}15.#Perform other_operation with non-blocking set to false5使用readpartialreadpartial被设计来用于就像socket这样的流.readpartial要求提供最大长度的参数,如果指定了buffer,那么这个buffer 应指向用于存储数据的一个字符串。