在Ruby中读取文件的常用方法是什么?

时间:2011-04-04 22:31:05

标签: ruby file-io

在Ruby中读取文件的所有常用方法是什么?

例如,这是一种方法:

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

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

11 个答案:

答案 0 :(得分:292)

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

puts File.read(file_name)

确实,IO.readFile.read会自动关闭文件,因此无需将File.open与块一起使用。

答案 1 :(得分:246)

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

答案 2 :(得分:211)

警惕“啜饮”文件。那是你一次将整个文件读入内存的时候。

问题是它不能很好地扩展。您可以使用合理大小的文件开发代码,然后将其投入生产并突然发现您正在尝试读取以千兆字节为单位的文件,并且主机在尝试读取和分配内存时会冻结。

逐行I / O非常快,几乎总是像啜饮一样有效。实际上它的速度非常快。

我喜欢使用:

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

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

文件继承自IO,foreach位于IO中,因此您可以使用。

我有一些基准测试显示尝试通过read与“Why is "slurping" a file not a good practice?”的逐行I / O读取大文件的影响。

答案 3 :(得分:67)

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

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

参考文献:File APIIO API

答案 4 :(得分:25)

一种简单的方法是使用readlines

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

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

答案 5 :(得分:17)

file_content = File.read('filename with extension');
puts file_content;

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

答案 6 :(得分:9)

我通常这样做:

open(path_in_string, &:read)

这将为整个文本提供一个字符串对象。它仅适用于Ruby 1.9。

答案 7 :(得分:4)

从your_file.log或.txt

返回最后 n
path = File.join(Rails.root, 'your_folder','your_file.log')

last_100_lines = `tail -n 100 #{path}`

答案 8 :(得分:0)

一种更有效的方法是通过请求操作系统的内核打开文件,然后一点一点地从文件中读取字节来进行流传输。在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 & Streaming Files By AppSignal

答案 9 :(得分:0)

如果文件较小(拖拉):

puts File.read("filename.txt")

如果文件很大(流):

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

答案 10 :(得分:-1)

content = `cat file`

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