4

我编写了以下脚本来读取 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

如果我取出该行,此代码运行良好:

 if (f.eof?)
     puts "End of file reached"

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

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

4

3 回答 3

7

试试这个简短的例子:

f = File.open(__FILE__)
text = f.read
p f.eof?      # -> true
p text.class #-> String

随着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

您应该在阅读后关闭该文件。为此使用块更像 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

一个一般性评论:Ruby 中有一个 CSV 库。通常最好使用它。

于 2013-07-13T21:29:48.313 回答
3

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

content = File.read("file.txt")
content = File.readlines("file.txt")

以上将整个文件“啜”到内存中。

File.foreach("file.txt") {|line| content << line}

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

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

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

有时最好的处理方式是不要,当你真的不需要时。

当然,Ruby 有一个方法可以做到这一点。

于 2013-07-13T21:30:26.730 回答
1

如果不对此进行测试,您似乎应该执行救援而不是检查。

http://www.ruby-doc.org/core-2.0/EOFError.html

file = File.open("aFile.csv")

begin
  loop do
    some_line = file.readline
    # some stuff
  end
rescue EOFError
  # You've reached the end. Handle it.
end
于 2013-07-13T21:15:43.993 回答