在Ruby中读取文件的常见方法有哪些?

在Ruby中读取文件的常见方法有哪些?

例如,这里有一个方法:

fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
puts(line)
end
fileObj.close

我知道Ruby非常灵活。每种方法的优点/缺点是什么?

375541 次浏览
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

如果文件不是太长,最简单的方法是:

puts File.read(file_name)

实际上,IO.readFile.read会自动关闭文件,所以不需要使用File.open作为块。

一个简单的方法是使用readlines:

my_array = IO.readlines('filename.txt')

输入文件中的每一行都是数组中的一个条目。该方法为您处理打开和关闭文件的操作。

我通常这样做:

open(path_in_string, &:read)

这将为您提供整个文本作为字符串对象。它只能在Ruby 1.9下工作。

小心“啜”;文件。这是指将整个文件一次性读入内存。

问题是它的可扩展性不好。您可能正在使用一个大小合理的文件开发代码,然后将其投入生产,突然发现您正在尝试读取以gb为单位的文件,并且您的主机在尝试读取和分配内存时死机了。

一行一行的I/O非常快,几乎总是像吮吸一样有效。实际上它的速度快得惊人。

我喜欢用:

IO.foreach("testfile") { |x| print "GOT ", x }

File.foreach('testfile') { |x| print "GOT", x }

File继承自IO,而foreach在IO中,所以你可以使用任何一个。

我有一些基准测试显示试图通过read读取大文件与逐行I/O在"https://stackoverflow.com/q/25189262/128421"的影响。

您可以一次读取所有文件:

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

对于二进制文件,你可以指定一个空分隔符和块大小,如下所示:

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

引用:文件APIIO API. c。

返回your_file.log或.txt中的最后n

path = File.join(Rails.root, 'your_folder','your_file.log')


last_100_lines = `tail -n 100 #{path}`
file_content = File.read('filename with extension');
puts file_content;

http://www.ruby-doc.org/core-1.9.3/IO.html#method-c-read

一种更有效的方法是流,它要求操作系统内核打开一个文件,然后一点一点地从中读取字节。在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 }

在这篇详细的文章中阅读:

Ruby Magic Slurping &流式文件通过AppSignal

content = `cat file`

我认为这种方法是最“不寻常”的一种。也许这有点棘手,但如果安装了cat,它就可以工作。

如果文件很小(吸声):

puts File.read("filename.txt")

如果文件很大(流媒体):

File.foreach("filename.txt") { |line| puts line }