如何检测Ruby中的文件结尾?

ban*_*ing 3 ruby csv parsing eof

我编写了以下脚本来读取CSV文件:

f = File.open("aFile.csv")
text = f.read
text.each_line do |line|
  if (f.eof?)
    puts "End of file reached"
  else
    line_num +=1
    if(line_num < 6) then
      puts "____SKIPPED LINE____"
      next
    end
  end

  arr = line.split(",")
  puts "line number  = #{line_num}" 
end
Run Code Online (Sandbox Code Playgroud)

如果我拿出这行代码,这段代码运行正常:

 if (f.eof?)
     puts "End of file reached"
Run Code Online (Sandbox Code Playgroud)

有了这条线,我得到了一个例外.

我想知道如何在上面的代码中检测文件的结尾.

knu*_*nut 5

试试这个简短的例子:

f = File.open(__FILE__)
text = f.read
p f.eof?      # -> true
p text.class #-> String
Run Code Online (Sandbox Code Playgroud)

随着f.read您将整个文件读入文本并达到EOF.(备注:__FILE__脚本文件本身.您可以使用csv文件).

在您使用的代码中text.each_line.这each_line将对字符串文本执行.它对...没有影响f.

您可以在File#each_line不使用变量文本的情况下使用.EOF的测试不是必需的.each_line每行循环并自行检测EOF.

f = File.open(__FILE__)
line_num = 0
f.each_line do |line|
  line_num +=1
  if (line_num < 6) 
     puts "____SKIPPED LINE____"
     next
  end

  arr = line.split(",")
  puts "line number  = #{line_num}" 
end
f.close
Run Code Online (Sandbox Code Playgroud)

您应该在阅读后关闭该文件.为此使用块更像Ruby:

line_num = 0
File.open(__FILE__) do | f|
  f.each_line do |line|
    line_num +=1
    if (line_num < 6) 
       puts "____SKIPPED LINE____"
       next
  end

    arr = line.split(",")
    puts "line number  = #{line_num}" 
  end
end
Run Code Online (Sandbox Code Playgroud)

一般说法:Ruby中有一个CSV库.通常最好使用它.


vgo*_*off 3

https://www.ruby-forum.com/topic/218093#946117讨论了这一点。

content = File.read("file.txt")
content = File.readlines("file.txt")
Run Code Online (Sandbox Code Playgroud)

上面的代码将整个文件“吞入”内存中。

File.foreach("file.txt") {|line| content << line}
Run Code Online (Sandbox Code Playgroud)

您也可以使用IO#each_line. 最后两个选项不会将整个文件读入内存。使用该块也会自动关闭您的 IO 对象。还有其他方法,IO 和 File 类的功能非常丰富!

我指的是 IO 对象,因为 File 是 IO 的子类。当我并不真正需要为对象添加 File 类的方法时,我倾向于使用 IO。

这样你就不需要处理EOF了,Ruby会帮你处理。

有时候,最好的处理方式就是当你确实不需要的时候不这样做。

当然,Ruby 有一个方法可以实现这一点。