- 浏览: 1400009 次
- 性别:
- 来自: 火星
文章分类
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
1 检测文件是否存在及其大小
FileTest的 exist?方法可以检测一个文件是否存在:
如果我们想要知道文件是否有内容,可以使用File::Stat的zero? 方法:
这个将会返回true,这是因为在ruby中0也是true,nil才是false.
所以我们可以使用size?方法:
FileTest模块里面也有zero? 和size?方法:
这里还有一个size方法:
2 检测特殊文件属性
这边要注意,File类mix了FIleTest模块,并且FileTest模块和File::Stat模块功能上也有很多重复.
unix/linux有面向字符和面向块的设备。FileTest的方法blockdev?和chardev?可以进行测试:
有时我们想要知道一个流是否联系到了终端,这时我们可以使用IO类的tty?方法:
一个流可以是一个管道,或者一个socket:
要区分目录和普通文件我们这样使用:
File还有一个类方法ftype,他将返回流的类型.他也在File::Stat里面,只不过是实例方法.它的返回值可能是下面的字符
串(file、directory、blockSpecial、characterSpecial、fifo、link或socket).
要测试一个文件是否为另一个文件的链接,可以使用FileTest的symlink?方法,要计算链接数量,可以使用nlink方法:
3 使用管道
ruby中使用IO.popen打开管道:
要注意 必须调用close_write,如果没有调用它,读取管道的时候,就不能到达文件的末尾.
下面是一个block的形式:
如果指定了一个字符串"-",那么一个新的ruby实例将被创建.如果指定了一个block,那么这个block将会作为两个独立
的进程运行。子进程得到nil,父进程得到一个IO对象:
pipe方法也返回互相连接的一对管道:
4 使用非阻塞IO
ruby会在后台执行一些操作,使io不会被阻断,因此大部分情况下可以使用ruby线程来管理IO,当一个线程被Io阻塞之
后,另外的线程能够继续执行.
由于ruby的线程不是一个native的线程,因此ruby的线程都在同一个进程里面.
如果你想关闭一个非阻塞io,你可以这样做:
5 使用readpartial
readpartial被设计来用于就像socket这样的流.
readpartial要求提供最大长度的参数,如果指定了buffer,那么这个buffer应指向用于存储数据的一个字符串。
readpartial 方法,不能接受非阻塞的flag,他有时会阻塞:IO对象的buffer是空的;流的内容为空;流没有到达文件末尾
。
因此,如果流中还有数据的话,readpartial将不会阻塞.
如果流没有数据,并且他已经抵达文件的末尾,readpartial 将会立即抛出一个EOFError.
如果调用阻塞,他将会等待直到接收到数据或者得到一个EOF.
当sysread 调用在阻塞模式下,他的行为与readpartial相似.
6 操作路径名
先来看一下File.dirname和File.basename方法:
File.split方法,可以将一个文件的路径名和文件名分隔开:
类方法expand_path 将一个相对路径,转换为一个绝对路径名:
对于打开的文件,path 将会返回这个文件的路径名:
类方法类方法join正好和split相反:
7使用Pathname
pathname类实际上是,Dir, File, FileTest,和FileUtils的包装器,它包含他们的很多功能:
再看看其他的有用的方法:
relative和absolute判断路径是否是相对的:
8 Command-Level 文件操作
其实也就是copy, delete, rename,等等 些操作了:
fileUtils也有很多有用的方法
9 从键盘抓取输入
也就是抓取用户从键盘输入的字符。
unix平台:
windows平台:
10 读取整个文件到内存
读取整个文件到数组,你不需要打开文件,IO.readlines 可以完成这个工作,他自己会open和close.
也可以用IO.read(它返回一个大的字符串):
由于File继承了IO,因此File也有这两个方法.
11 逐行迭代一个文件
我们可以使用IO.foreach 方法,或者each方法,如果是前者文件不需要显示打开:
12逐字节对文件进行遍历
可以使用each_byte方法,如果你想要转换byte到字符的话使用chr方法:
12 把字符串当文件来用
我们可以使用stringio库:
13读取嵌套在程序中的数据
ruby中程序末尾的__END__ 标记说明,下面的数据是程序内嵌的数据,你可以使用一个IO对象DATA来读取。
14 读取程序源码
DATA指向__END__ 后面的数据,如果你调用rewind,它将会将文件指针指向程序的开头:
15 操作临时文件
这里使用Tempfile库:
16 改变和设置当前目录
得到当前的目录可以使用Dir.pwd或他的别名Dir.getwd来获得.
Dir.chdir 用来改变当前目录:
这个还能接受一个block,接受block说明,block里的代码都是在改变了的目录下进行的:
17改变当前根目录
18 遍历一个目录
19 创建一个目录链
在linux使用mkdir -p来做,在ruby中我么可以这么做:
20 递归的删除目录
在linux下我们能够使用rm -rf ...来做,在ruby中我们能这么做:
21 查找文件和目录
使用find库来做:
FileTest的 exist?方法可以检测一个文件是否存在:
flag = FileTest::exist?("LochNessMonster") flag = FileTest::exists?("UFO") # exists? is a synonym for exist?
如果我们想要知道文件是否有内容,可以使用File::Stat的zero? 方法:
flag = File.new("somefile").stat.zero?
这个将会返回true,这是因为在ruby中0也是true,nil才是false.
所以我们可以使用size?方法:
if File.new("myfile").stat.size? puts "The file has contents." else puts "The file is empty." end
FileTest模块里面也有zero? 和size?方法:
flag1 = FileTest::zero?("file1") flag2 = FileTest::size?("file2")
这里还有一个size方法:
size1 = File.size("file1") size2 = File.stat("file2").size
2 检测特殊文件属性
这边要注意,File类mix了FIleTest模块,并且FileTest模块和File::Stat模块功能上也有很多重复.
unix/linux有面向字符和面向块的设备。FileTest的方法blockdev?和chardev?可以进行测试:
flag1 = FileTest::chardev?("/dev/hdisk0") # false flag2 = FileTest::blockdev?("/dev/hdisk0") # true
有时我们想要知道一个流是否联系到了终端,这时我们可以使用IO类的tty?方法:
flag1 = STDIN.tty? # true flag2 = File.new("diskfile").isatty # false
一个流可以是一个管道,或者一个socket:
flag1 = FileTest::pipe?(myfile) flag2 = FileTest::socket?(myfile)
要区分目录和普通文件我们这样使用:
file1 = File.new("/tmp") file2 = File.new("/tmp/myfile") test1 = file1.directory? # true test2 = file1.file? # false test3 = file2.directory? # false test4 = file2.file? # true
File还有一个类方法ftype,他将返回流的类型.他也在File::Stat里面,只不过是实例方法.它的返回值可能是下面的字符
串(file、directory、blockSpecial、characterSpecial、fifo、link或socket).
this_kind = File.ftype("/dev/hdisk0") # "blockSpecial" that_kind = File.new("/tmp").stat.ftype # "directory"
要测试一个文件是否为另一个文件的链接,可以使用FileTest的symlink?方法,要计算链接数量,可以使用nlink方法:
File.symlink("yourfile","myfile") # Make a link is_sym = FileTest::symlink?("myfile") # true hard_count = File.new("myfile").stat.nlink # 0
3 使用管道
ruby中使用IO.popen打开管道:
check = IO.popen("spell","r+") check.puts("'T was brillig, and the slithy toves") check.puts("Did gyre and gimble in the wabe.") check.close_write list = check.readlines list.collect! { |x| x.chomp } # list is now %w[brillig gimble gyre slithy toves wabe]
要注意 必须调用close_write,如果没有调用它,读取管道的时候,就不能到达文件的末尾.
下面是一个block的形式:
File.popen("/usr/games/fortune") do |pipe| quote = pipe.gets puts quote # On a clean disk, you can seek forever. - Thomas Steel end
如果指定了一个字符串"-",那么一个新的ruby实例将被创建.如果指定了一个block,那么这个block将会作为两个独立
的进程运行。子进程得到nil,父进程得到一个IO对象:
IO.popen("-") do |mypipe| if mypipe puts "I'm the parent: pid = #{Process.pid}" listen = mypipe.gets puts listen else puts "I'm the child: pid = #{Process.pid}" end end # Prints: # I'm the parent: pid = 10580 # I'm the child: pid = 10582
pipe方法也返回互相连接的一对管道:
pipe = IO.pipe reader = pipe[0] writer = pipe[1] str = nil thread1 = Thread.new(reader,writer) do |reader,writer| # writer.close_write str = reader.gets reader.close end thread2 = Thread.new(reader,writer) do |reader,writer| # reader.close_read writer.puts("What hath God wrought?") writer.close end thread1.join thread2.join puts str # What hath God wrought?
4 使用非阻塞IO
ruby会在后台执行一些操作,使io不会被阻断,因此大部分情况下可以使用ruby线程来管理IO,当一个线程被Io阻塞之
后,另外的线程能够继续执行.
由于ruby的线程不是一个native的线程,因此ruby的线程都在同一个进程里面.
如果你想关闭一个非阻塞io,你可以这样做:
require 'io/nonblock' # ... test = mysock.nonblock? # false mysock.nonblock = true # turn off blocking # ... mysock.nonblock = false # turn on again mysock.nonblock { some_operation(mysock) } # Perform some_operation with nonblocking set to true mysock.nonblock(false) { other_operation(mysock) } # Perform other_operation with non-blocking set to false
5 使用readpartial
readpartial被设计来用于就像socket这样的流.
readpartial要求提供最大长度的参数,如果指定了buffer,那么这个buffer应指向用于存储数据的一个字符串。
data = sock.readpartial(128) # Read at most 128 bytes
readpartial 方法,不能接受非阻塞的flag,他有时会阻塞:IO对象的buffer是空的;流的内容为空;流没有到达文件末尾
。
因此,如果流中还有数据的话,readpartial将不会阻塞.
如果流没有数据,并且他已经抵达文件的末尾,readpartial 将会立即抛出一个EOFError.
如果调用阻塞,他将会等待直到接收到数据或者得到一个EOF.
当sysread 调用在阻塞模式下,他的行为与readpartial相似.
6 操作路径名
先来看一下File.dirname和File.basename方法:
str = "/home/dave/podbay.rb" dir = File.dirname(str) # "/home/dave" file1 = File.basename(str) # "podbay.rb" file2 = File.basename(str,".rb") # "podbay"
File.split方法,可以将一个文件的路径名和文件名分隔开:
info = File.split(str) # ["/home/dave","podbay.rb"]
类方法expand_path 将一个相对路径,转换为一个绝对路径名:
Dir.chdir("/home/poole/personal/docs") abs = File.expand_path("../../misc") # "/home/poole/misc"
对于打开的文件,path 将会返回这个文件的路径名:
file = File.new("../../foobar") name = file.path # "../../foobar"
类方法类方法join正好和split相反:
path = File.join("usr","local","bin","someprog")
7使用Pathname
pathname类实际上是,Dir, File, FileTest,和FileUtils的包装器,它包含他们的很多功能:
require 'pathname' path = Pathname.new("home/hal") file = Pathname.new("file.txt") p2 = path + file path.directory? # true path.file? # false p2.directory? # false p2.file? # true puts parts = p2.split # [Pathname:/home/hal, Pathname:file.txt] puts ext = p2.extname # .txt
再看看其他的有用的方法:
p1 = Pathname.new("//") # odd but legal p1.root? # true p2 = Pathname.new("/home/poole") p3 = p2.parent # Pathname:/home items = p2.children # array of Pathnames (all files and # dirs immediately under poole)
relative和absolute判断路径是否是相对的:
p1 = Pathname.new("/home/dave") p1.absolute? # true p1.relative? # false
8 Command-Level 文件操作
其实也就是copy, delete, rename,等等 些操作了:
File.delete("history") File.unlink("toast") File.rename("Ceylon","SriLanka") File.link("/etc/hosts","/etc/hostfile") # hard link File.symlink("/etc/hosts","/tmp/hosts") # symbolic link File.truncate("myfile",1000) # Now at most 1000 bytes
fileUtils也有很多有用的方法
require "fileutils" same = FileUtils.compare_file("alpha","beta") # true # Copy epsilon to theta and log any errors. FileUtils.copy("epsilon","theta", true) FileUtils.move("/tmp/names","/etc") # Move to new directory FileUtils.move("colours","colors") # Just a rename FileUtils.safe_unlink("alpha","beta","gamma") # Log errors on the next two files FileUtils.safe_unlink("delta","epsilon",true) FileUtils.install("foo.so","/usr/lib")
9 从键盘抓取输入
也就是抓取用户从键盘输入的字符。
unix平台:
def getchar system("stty raw -echo") # Raw mode, no echo char = STDIN.getc system("stty -raw echo") # Reset terminal mode char end
windows平台:
require 'Win32API' def getchar char = Win32API.new("crtdll", "_getch", [], 'L').Call end
10 读取整个文件到内存
读取整个文件到数组,你不需要打开文件,IO.readlines 可以完成这个工作,他自己会open和close.
arr = IO.readlines("myfile") lines = arr.size puts "myfile has #{lines} lines in it." longest = arr.collect {|x| x.length}.max puts "The longest line in it has #{longest} characters."
也可以用IO.read(它返回一个大的字符串):
str = IO.read("myfile") bytes = arr.size puts "myfile has #{bytes} bytes in it." longest = str.collect {|x| x.length}.max # strings are enumerable! puts "The longest line in it has #{longest} characters."
由于File继承了IO,因此File也有这两个方法.
11 逐行迭代一个文件
我们可以使用IO.foreach 方法,或者each方法,如果是前者文件不需要显示打开:
# Print all lines containing the word "target" IO.foreach("somefile") do |line| puts line if line =~ /target/ end # Another way... file = File.new("somefile") file.each do |line| puts line if line =~ /target/ end
12逐字节对文件进行遍历
可以使用each_byte方法,如果你想要转换byte到字符的话使用chr方法:
file = File.new("myfile") e_count = 0 file.each_byte do |byte| e_count += 1 if byte == ?e end
12 把字符串当文件来用
我们可以使用stringio库:
require 'stringio' ios = StringIO.new("abcdefghijkl\nABC\n123") ios.seek(5) ios.puts("xyz") puts ios.tell # 8 puts ios.string.dump # "abcdexyzijkl\nABC\n123" c = ios.getc puts "c = #{c}" # c = 105 ios.ungetc(?w) puts ios.string.dump # "abcdexyzwjkl\nABC\n123" puts "Ptr = #{ios.tell}" s1 = ios.gets # "wjkl" s2 = ios.gets # "ABC"
13读取嵌套在程序中的数据
ruby中程序末尾的__END__ 标记说明,下面的数据是程序内嵌的数据,你可以使用一个IO对象DATA来读取。
# Print each line backwards... DATA.each_line do |line| puts line.reverse end __END__ A man, a plan, a canal... Panama! Madam, I'm Adam. ,siht daer nac uoy fI .drah oot gnikrow neeb ev'uoy
14 读取程序源码
DATA指向__END__ 后面的数据,如果你调用rewind,它将会将文件指针指向程序的开头:
DATA.rewind num = 1 DATA.each_line do |line| puts "#{'%03d' % num} #{line}" num += 1 end __END__
15 操作临时文件
这里使用Tempfile库:
require "tempfile" temp = Tempfile.new("stuff") name = temp.path # "/tmp/stuff17060.0" temp.puts "Kilroy was here" temp.close # Later... temp.open str = temp.gets # "Kilroy was here" temp.close(true) # 立即删除
16 改变和设置当前目录
得到当前的目录可以使用Dir.pwd或他的别名Dir.getwd来获得.
Dir.chdir 用来改变当前目录:
Dir.chdir("/var/tmp") puts Dir.pwd # "/var/tmp" puts Dir.getwd # "/var/tmp"
这个还能接受一个block,接受block说明,block里的代码都是在改变了的目录下进行的:
Dir.chdir("/home") Dir.chdir("/tmp") do puts Dir.pwd # /tmp # other code... end puts Dir.pwd # /home
17改变当前根目录
Dir.chdir("/home/guy/sandbox/tmp") Dir.chroot("/home/guy/sandbox") puts Dir.pwd # "/tmp"
18 遍历一个目录
Dir.foreach("/tmp") { |entry| puts entry } dir = Dir.new("/tmp") dir.each { |entry| puts entry }
19 创建一个目录链
在linux使用mkdir -p来做,在ruby中我么可以这么做:
require "fileutils" FileUtils.makedirs("/tmp/these/dirs/need/not/exist")
20 递归的删除目录
在linux下我们能够使用rm -rf ...来做,在ruby中我们能这么做:
require 'pathname' dir = Pathname.new("/home/poole/") dir.rmtree # or: require 'fileutils' FileUtils.rm_r("/home/poole")
21 查找文件和目录
使用find库来做:
require "find" def findfiles(dir, name) list = [] Find.find(dir) do |path| Find.prune if [".",".."].include? path case name when String list << path if File.basename(path) == name when Regexp list << path if File.basename(path) =~ name else raise ArgumentError end end list end findfiles "/home/hal", "toc.txt" # ["/home/hal/docs/toc.txt", "/home/hal/misc/toc.txt"] findfiles "/home", /^[a-z]+.doc/ # ["/home/hal/docs/alpha.doc", "/home/guy/guide.doc", # "/home/bill/help/readme.doc"]
发表评论
-
一个创建闭包的小技巧
2008-06-05 00:12 2134一个小技巧,在Ola Bini 的blog上看到的。 假设你 ... -
解决Colored Cubes问题
2008-06-02 10:43 2785Engineering Puzzle You have fo ... -
ruby1.9中的Iterators
2008-03-05 22:37 3719在ruby1.9中增加了External Iterators这 ... -
一个简单的ruby Metaprogram的例子
2008-03-03 23:49 4104比如下面一个文件 people.txt 引用name,age ... -
Ruby Object Model
2008-03-03 19:29 3576刚好看到,保存一下. -
一个检测方法的参数类型的小程序
2008-03-02 22:48 3249今天没事看blog的时候,看到一个小子实现了这个,不过他的程序 ... -
rails中的BlankSlate源码分析
2008-02-28 23:27 3446其实这个类实现的功能很简单,那就是实现一个没有predefin ... -
ruby中的类变量与类实例变量
2008-02-26 21:15 7636首先,在ruby1.8中类变量是所有子类和父类共享的,可以看下 ... -
在ubuntu上共存多个版本的ruby
2008-02-24 15:20 4377今天装Revactor库的时候,真把我郁闷了,没想到ubunt ... -
看到了一个用ruby写的scheme解释器
2008-02-16 21:35 3771,自己本来想等啥时候有时间做个类似的东西呢,没想到已经有人做 ... -
ruby way之处理RSS和Atom
2008-01-31 01:32 35211 rss 标准库 RSS 是基于xml的,因此你能简单的将 ... -
ruby way之使用REXML解析xml
2008-01-30 00:35 9254REXML 是一个完全用ruby写的processor ,他有 ... -
rails2中的一些被废弃的用法
2008-01-29 00:33 2544这些只是自己最近看web开发敏捷之道的时候(由于书中的版本是1 ... -
ruby way之动态特性之二
2008-01-25 00:49 36801 得到所定义的实体的列表 ruby的反射api能够使我们在 ... -
ruby way之动态特性之一
2008-01-23 01:25 45441 动态的evaluate代码 全局的方法eval 编译并且 ... -
ruby way之高级OOP特性之二
2008-01-20 03:43 29491 把代码像对象一样存储 当你想要以对象的形式存储一块代码的 ... -
ruby way之高级OOP特性之一
2008-01-19 12:14 22651 发送一条消息给一个对象 当你调用一个方法时,你也就是发送 ... -
ruby way之OOP之二
2008-01-16 23:59 23641 理解allocate 在一些特殊的环境中,你可能需要不调 ... -
ruby way之OOP之一
2008-01-16 00:25 26331 使用多个构造方法 在ruby中没有像c++或者ruby中 ... -
ruby way之连接数据库
2008-01-14 00:47 2475这边都只是个大概,具体的要自己去看文档了. 1 连接SQLi ...
相关推荐
The Ruby Way(第2版) <br>The Ruby Way assumes that the reader is already familiar with the subject matter. Using many code samples it focuses on "how-to use Ruby" for specific applications, either ...
The Ruby Way 第三版(英文版),全书22章,书中包含600多个按主题分类的示例。每个示例都回答了“如何使用Ruby来完成”的问题。 ——Ruby on Rails之父David Heinemeier Hansson倾力推荐!
《The Ruby Way 第二版》...“《The Ruby Way (第2版)中文版》在阐述元编程(metaprogramming)等方面尤其出类拔萃,而元编程是Ruby最引人注目的方面之一。” ——Ruby on Rails之父David Heinemeier Hansson倾力推荐!
这本书的第二版在2006年出版,由Addison-Wesley出版,作者通过深入浅出的方式,揭示了Ruby语言的强大功能和优雅特性。 Ruby是一种动态类型、面向对象的编程语言,它的设计理念是注重简洁和生产力,让开发者能够更...
内含以下4个文档: 1、Addison.Wesley.The.Ruby.Way.2nd.Edition.Oct.2006.chm 2、O'Reilly.Learning.Ruby.May.2007.chm 3、Programming Ruby 2e.pdf 4、ruby中文文档.chm
stream-ruby, ruby 客户端生成活动使用 GetStream.io 提供&流 流 ruby 是一款用于构建可以伸缩新闻发布和活动流的web服务的官方 ruby 客户端,它是流。注意,还有一个更高级的 Ruby on Rails - 流集成插件库,它将...
the ruby way the ruby way
rubywork ruby编程例子 逻辑 IO 数据库rubywork ruby编程例子 逻辑 IO 数据库 rubywork ruby编程例子 逻辑 IO 数据库rubywork ruby编程例子 逻辑 IO 数据库rubywork ruby编程例子 逻辑 IO 数据库
《The Ruby Way》第二版是Addison-Wesley出版社在2006年10月出版的一本关于Ruby编程语言的权威指南。这本书深入浅出地介绍了Ruby语言的核心特性和高级用法,旨在帮助读者全面理解和掌握Ruby的精髓。通过阅读这本书,...
### Addison Wesley《The Ruby Way》第二版(2006年10月) #### 书籍概览 《The Ruby Way》是由Hal Fulton编写的关于Ruby编程语言的经典著作,该书的第二版出版于2006年10月,由Addison Wesley Professional出版社...
cool.io, ruby的简单主题 I/O ( 但请检查赛车) Cool.io如果你对基于赛璐珞的IO框架感兴趣,...Cool.io 是 ruby的事件库,构建在libev事件库之上,它提供了一个跨平台接口,用于高性能。 这包括Linux的epoll系统调用,bs
"11.5 时间日期the ruby way"这个主题深入探讨了Ruby中处理时间日期的最佳实践和常见用法。让我们逐一了解这些知识点。 首先,`Time.now`是Ruby中获取当前时间的标准方法。它返回一个`Time`对象,表示自1970年1月1...
《Ruby Way》是由Hal Fulton编写的关于Ruby编程语言的一本著作。这本书深入浅出地探讨了Ruby语言的各种特性,旨在帮助读者理解并掌握这门强大的动态脚本语言。Ruby以其简洁、优雅的语法和强大的元编程能力而备受赞誉...
Ruby-Async是建立在这个理念之上,通过nio4r库来实现对多种I/O事件的监听。nio4r是一个用于非阻塞I/O操作的高性能库,它基于Java的NIO(非阻塞I/O)接口,为Ruby提供了类似的功能。nio4r提供了一种高效的方式来注册...
它继承自`IO`类,这意味着所有`IO`类提供的功能都可以在`File`类中使用。通过`File.new`方法可以创建并打开一个文件对象,该方法接收文件名作为第一个参数。 **模式字符串**: 可以通过指定第二个参数来设置文件的...