您的位置:首页 > 编程语言 > Ruby

ruby文件读写的好文章 ruby way之IO之一

2012-03-21 13:41 393 查看

http://simohayha.javaeye.com/blog/153398

1 打开和关闭一个文件

类方法File.new 打开一个文件,并将它实例化为一个File对象,他的第一个参数是文件名.

可选的第二个参数叫做 mode string(这个也是从c得来的).他的意思是怎样打开一个文件(读,写或者其他的).默认是'r'(也就是读).

Ruby代码

file1 = File.new("one") # Open for reading

file2 = File.new("two","w") # Open for writing

file1 = File.new("one")       # Open for reading  file2 = File.new("two", "w")  # Open for writing
另外一种new的形式是三个参数的,其中第二个参数是指定了这个文件的原始的权限(经常表示为一个八进制的数).第三个参数是一系列Ored标志 的组合.标志是个常量比如File:CREAT(如果文件不存在则创建它)和File:RDONLY(以只读方式打开文件)。不过这种形式很少使用:

Ruby代码

file = File.new("three", 0755,File::CREAT|File::WRONLY)

file = File.new("three", 0755, File::CREAT|File::WRONLY)


出于对操作系统和运行环境的考虑,如果你打开了一个文件的话,你就必须关闭它。当你打开一个文件用于写时,你更应该这样做,从而才能免于丢失数据.close方法就是关闭一个文件:

Ruby代码

out = File.new("captains.log","w")

# Process as needed...
out.close

out = File.new("captains.log", "w") # Process as needed... out.close


这里还有一个open方法,它的最简单的形式是和new同义的:

Ruby代码

trans = File.open("transactions","w")

trans = File.open("transactions","w")


但是open方法还能够带一个block作为参数,当存在block时,打开的文件将会做为一个参数传递给block.这时这个文件将会在这个block的作用域里,保持打开,直到block结束时,自动关闭:

Ruby代码

File.open("somefile","w")do |file|

file.puts "Line 1"
file.puts "Line 2"
file.puts "Third and final line"
end

File.open("somefile","w") do |file|   file.puts "Line 1"   file.puts "Line 2"   file.puts "Third and final line" end


2 更新文件

假设我们想要打开一个文件用于读和写,简单的加一个'+'号到file mode就行了:

Ruby代码

f1 = File.new("file1","r+")

# Read/write, starting at beginning of file.
f2 = File.new("file2","w+")

# Read/write; truncate existing file or create a new one.
f3 = File.new("file3","a+")

# Read/write; start at end of existing file or create a
# new one.

f1 = File.new("file1", "r+") # Read/write, starting at beginning of file. f2 = File.new("file2", "w+") # Read/write; truncate existing file or create a new one. f3 = File.new("file3", "a+") # Read/write; start at end of existing file or create a # new one.


3 追加一个文件

假设我们想要追加一段信息到一个存在文件,当我们打开文件时使用'a'作为file mode就行了:

Ruby代码

logfile = File.open("captains_log","a")

# Add a line at the end, then close.
logfile.puts "Stardate 47824.1: Our show has been canceled."
logfile.close

logfile = File.open("captains_log", "a") # Add a line at the end, then close. logfile.puts "Stardate 47824.1: Our show has been canceled." logfile.close


4随机存取一个文件

如果你想随即存取一个文件,你能够使用seek方法,它是File从Io继承而来的.它的最简单的使用就是指定一个字节位置.这个位置是相对于文件开始的位置(开始的位置是0):

Ruby代码

# myfile contains only: abcdefghi
file = File.new("myfile")
file.seek(5)
str = file.gets # "fghi"

# myfile contains only: abcdefghi file = File.new("myfile") file.seek(5) str = file.gets                   # "fghi"


如果你能确定每一行都是固定的长度,你就能seek指定的行:

Ruby代码

# Assume 20 bytes per line.
# Line N starts at byte (N-1)*20
file = File.new("fixedlines")
file.seek(5*20) # Sixth line!
# Elegance is left as an exercise.

# Assume 20 bytes per line. # Line N starts at byte (N-1)*20 file = File.new("fixedlines") file.seek(5*20)                   # Sixth line! # Elegance is left as an exercise.
如果你想做一个相对的搜索,你就要使用第二个参数,常量 IO::SEEK_CUR表示当前的位置,而第一个参数则就是相对于当前位置的偏移量(可能是负数):

Ruby代码

file = File.new("somefile")
file.seek(55) # Position is 55
file.seek(-22, IO::SEEK_CUR) # Position is 33
file.seek(47, IO::SEEK_CUR) # Position is 80

file = File.new("somefile") file.seek(55)                 # Position is 55 file.seek(-22, IO::SEEK_CUR)  # Position is 33 file.seek(47, IO::SEEK_CUR)   # Position is 80


你也能从文件的结束位置开始搜索:

Ruby代码

file.seek(-20, IO::SEEK_END) # twenty bytes from eof

file.seek(-20, IO::SEEK_END)  # twenty bytes from eof
方法tell得到文件的当前位置,pos是它的别名:

Ruby代码

file.seek(20)
pos1 = file.tell # 20
file.seek(50, IO::SEEK_CUR)
pos2 = file.pos # 70

file.seek(20) pos1 = file.tell             # 20 file.seek(50, IO::SEEK_CUR) pos2 = file.pos              # 70
rewind方法将会将文件指针的位置设回到开始的位置,也就是0.

5 操作二进制文件

在很久以前,c语言通过在file mode后附加一个'b'来表示将文件用二进制模式打开.在今天,二进制文件的处理已经没有那么麻烦了。在ruby中,一个字符串很容易保存一个二进制数据,而且也不用通过任何特殊的方式来读文件.

可是在windows下是例外,在他下面,二进制文件和文本文件的不同是,在二进制mode下,结束行不能被转义为一个单独的换行,而是被保存为一个回车换行对.

另外的不同是,在文本模式下 control-Z被作为文件的结束:

Ruby代码

# Create a file (in binary mode)
File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") }
# Above note the embedded octal 032 (^Z)
# Read it as binary
str = nil

File.open("myfile","rb") {|f| str = f.sysread(15) }
puts str.size # 11
# Read it as text
str = nil
File.open("myfile","r") {|f| str = f.sysread(15) }
puts str.size # 5

# Create a file (in binary mode) File.open("myfile","wb") {|f| f.syswrite("12345\0326789\r") } # Above note the embedded octal 032 (^Z) # Read it as binary str = nil  File.open("myfile","rb") {|f| str = f.sysread(15) } puts str.size           # 11 # Read it as text str = nil File.open("myfile","r") {|f| str = f.sysread(15) } puts str.size           # 5
这边注意,这些代码都是在windows下才会打印出后面的结果,如果是在linux两处都会打印出11.

再看下面的代码:

Ruby代码

# Input file contains a single line: Line 1.
file = File.open("data")
line = file.readline # "Line 1.\n"
puts "#{line.size} characters." # 8 characters
file.close
file = File.open("data","rb")
line = file.readline # "Line 1.\r\n"
puts "#{line.size} characters." # 9 characters 二进制模式的结尾是一个回车换行对.
file.close

# Input file contains a single line: Line 1. file = File.open("data") line = file.readline             # "Line 1.\n" puts "#{line.size} characters."  # 8 characters file.close file = File.open("data","rb") line = file.readline             # "Line 1.\r\n" puts "#{line.size} characters."  # 9 characters 二进制模式的结尾是一个回车换行对. file.close
binmode方法能够转换当前的流为二进制模式,这边要注意的是,一旦切换过去,就不能切换回来了:

Ruby代码

file = File.open("data")
file.binmode
line = file.readline # "Line 1.\r\n"
puts "#{line.size} characters." # 9 characters
file.close

file = File.open("data") file.binmode line = file.readline             # "Line 1.\r\n" puts "#{line.size} characters."  # 9 characters file.close
如果你想使用更底层的输入输出,那你可以选择sysread和syswrite方法,他们接受一定数量的字节作为参数 .

Ruby代码

input = File.new("myfile",'a+')
output = File.new("outfile",'a+')
instr = input.sysread(10);
puts instr
bytes = output.syswrite("This is a test.")

input = File.new("myfile",'a+') output = File.new("outfile",'a+') instr = input.sysread(10); puts instr bytes = output.syswrite("This is a test.")

如果文件指针已经到达文件的结尾时,sysread方法将会抛出一个异常.

这边要注意 Array 的pack和string的unpack方法,对于处理二进制数据非常有用.

=======================================================

读文件:

第一种方法:

$result='d:\\rs.txt'

File.open($result, "r") do |file|

file.each_line do |line|

if line.length>20

puts line.chop.length #去掉最后一个换行字符,并显示该行实际字符串的长度

puts line

end

end

end

第二种方法:

filename='d:\\rs.txt'

while File.exists?(filename) #如果源文件存在就执行下面的操作

file=File.open(filename,'r')

while (lines=file.gets)

puts lines

end

写文件:

$filename="C:\\Automation\\rss"+".txt"

$logfile = File.new($filename,"a")

iCount=0

while(iCount<10) //循环写入10行

$logfile.puts "http://xxxx/rs#{iCount}.xml"

iCount=iCount+1

end

今天又笨了一次,由于要比较两个文件的不同,于是考虑用ruby来写个脚本

实现,刚开始的时候使用双重

File.open($file1, "r") do |file1|

file1.each_line do |line1|

总是报错,

后来改成先把文件读到一个数组里,然后循环比较,成功.

其实这是个笨方法,在unix下使用三个命令就可以完成了.

1.先使用sort指令将文件中的数据按照要求的索引进行排序,

2.然后使用uniq指令将重复数据去掉

3.再使用diff命令就可以了.

========================================

ruby读写文本文件的简单例子,除了演示文本文件的读写外,这段ruby程序可以从文本文件中删除包含某些字符串的行。

用法:ruby delline.rb 文件名 字符串1 字符串2 字符串n

将删除同时包含字符串1 字符串2 字符串n的行。

ruby的开发环境这里下载

http://www.ruby-lang.org/en/downloads/

直接下载最近的稳定版Windows安装包

http://rubyforge.org/frs/download.php/29263/ruby186-26.exe

代码如下

下载:
delline.rb

ifARGV.length<2then
puts "USAGE: ruby delline.rb text_file_name str1 [str2 ...]"
exit
end

i_file_name =
ARGV[0]
i_file_name_bak =
i_file_name +".bak"
if FileTest.exist?(i_file_name)then
File.rename(i_file_name,i_file_name_bak)
else
puts "File #{i_file_name} was not found"
exit
end

i_file = File.new(i_file_name_bak,"r")
o_file = File.new(i_file_name,"w")

i_file.each_line do |line|
delete_flag =true
1.upto(ARGV.length
- 1) do |x|
if !line.include?(ARGV[x]) then
delete_flag =false
break
end
end
o_file.puts lineif
!delete_flag
end

i_file.close
o_file.close

File.open("cmd.txt","r") do |file|

while line=file.gets

puts line

end

end

puts

file=File.new("cmd.txt","r")

file.each_line do |line|

puts line

end

IO.foreach("cmd.txt") do |line|

puts line if line =~ /target/

puts line if line !~ /target/

end

# Another way...

file = File.new("cmd.txt")

file.each do |line|

puts line if line =~ /target/

end

arr = IO.read("cmd.txt")

bytes = arr.size

puts "myfile has #{bytes} bytes in it."

arr = IO.readlines("cmd.txt")

puts arr

lines = arr.size

puts "myfile has #{lines} lines in it."

file2=File.new("cmd.txt");

puts File.expand_path("cmd.txt")

file = File.new("cmd.txt")

e_count = 0

file.each_byte do |byte|

e_count += 1 if byte == ?e

end

puts File.exist?("testR.txt")

file1=File.new("testR.txt","w") #没有文件则会自动创建

puts File.exist?("testR.txt")

puts file1.write("ttt333\nttt444\n")

字符串当文件用.rb

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"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: