在Ruby中读取文件的所有常用方法有哪些?
例如,这是一种方法:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
我知道Ruby非常灵活。每种方法的优点/缺点是什么?
在Ruby中读取文件的所有常用方法有哪些?
例如,这是一种方法:
fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close
我知道Ruby非常灵活。每种方法的优点/缺点是什么?
Answers:
File.open("my/file/path", "r") do |f|
f.each_line do |line|
puts line
end
end
# File is closed automatically at end of block
也可以在上述之后显式关闭文件(传递一个块open
为您关闭文件):
f = File.open("my/file/path", "r")
f.each_line do |line|
puts line
end
f.close
foreach
而不是并不open
需要该each_line
块。
f.each { |line| ... }
并且f.each_line { |line| ... }
似乎具有相同的行为(至少在Ruby 2.0.0中)。
如果文件不太长,最简单的方法是:
puts File.read(file_name)
实际上,IO.read
或者File.read
自动关闭文件,因此不需要File.open
与块一起使用。
IO.read
或File.read
自动关闭文件,尽管您的措辞听起来像他们没有。
警惕“含糊”文件。那是您一次将整个文件读入内存的时候。
问题在于它的伸缩性不好。您可能正在开发具有合理大小的文件的代码,然后将其投入生产,突然发现您正在尝试读取以GB为单位的文件,并且主机在尝试读取和分配内存时处于冻结状态。
逐行I / O速度非常快,并且几乎总是像制浆一样有效。实际上,它出奇地快。
我喜欢使用:
IO.foreach("testfile") {|x| print "GOT ", x }
要么
File.foreach('testfile') {|x| print "GOT", x }
文件继承自IO,并且foreach
位于IO中,因此您可以使用其中任何一个。
我有一些基准测试,它显示了read
“ 为什么“吸引”文件不是一个好习惯? ” 尝试通过vs.逐行I / O 读取大文件的影响。
您可以一次读取所有文件:
content = File.readlines 'file.txt'
content.each_with_index{|line, i| puts "#{i+1}: #{line}"}
当文件很大或可能很大时,通常最好逐行处理它:
File.foreach( 'file.txt' ) do |line|
puts line
end
有时,您可能想要访问文件句柄或自己控制读取:
File.open( 'file.txt' ) do |f|
loop do
break if not line = f.gets
puts "#{f.lineno}: #{line}"
end
end
对于二进制文件,您可以指定一个nil-separator和一个块大小,如下所示:
File.open('file.bin', 'rb') do |f|
loop do
break if not buf = f.gets(nil, 80)
puts buf.unpack('H*')
end
end
最后,您可以无障碍地执行此操作,例如,当同时处理多个文件时。在这种情况下,必须显式关闭文件(根据@antinome的注释进行改进):
begin
f = File.open 'file.txt'
while line = f.gets
puts line
end
ensure
f.close
end
while
而不是loop
和ensure
来确保即使引发异常也可以关闭文件。像这样(更换分号用换行)begin; f = File.open('testfile'); while line = f.gets; puts line; end; ensure; f.close; end
。
file_content = File.read('filename with extension');
puts file_content;
我通常这样做:
open(path_in_string, &:read)
这将为您提供整个文本作为字符串对象。它仅在Ruby 1.9下有效。
从your_file.log或.txt 返回最后n行
path = File.join(Rails.root, 'your_folder','your_file.log')
last_100_lines = `tail -n 100 #{path}`
一种更有效的方法是通过要求操作系统的内核打开文件,然后一点一点地从文件中读取字节来进行流传输。在Ruby中,每行读取一个文件时,一次从512字节的文件中提取数据,然后分成“行”。
通过缓冲文件的内容,减少了I / O调用的数量,同时将文件划分为多个逻辑块。
例:
将此类作为服务对象添加到您的应用中:
class MyIO
def initialize(filename)
fd = IO.sysopen(filename)
@io = IO.new(fd)
@buffer = ""
end
def each(&block)
@buffer << @io.sysread(512) until @buffer.include?($/)
line, @buffer = @buffer.split($/, 2)
block.call(line)
each(&block)
rescue EOFError
@io.close
end
end
调用它并将:each
方法传递给一个块:
filename = './somewhere/large-file-4gb.txt'
MyIO.new(filename).each{|x| puts x }
在此详细信息中阅读有关此内容的信息: