Ruby日志文件在Windows上不起作用,但适用于Mac OS?

时间:2013-10-03 18:46:35

标签: ruby windows macos logging

我写了一个在Mac上运行的脚本就好了。它有这行代码:

filename = "2011"
  File.open(filename, File::WRONLY|File::CREAT|File::EXCL) do |logfile|
    logfile.puts "MemberID,FirstName,LastName,BadEmail,gender,dateofbirth,ActiveStatus,Phone" 

在Windows上,脚本运行正常并且它创建了日志文件2011,但它实际上并没有puts该日志文件的任何内容,因此创建了文件,脚本运行,但是日志记录没有不会发生。

有谁知道为什么?我想不出脚本的实际功能会发生什么变化会导致日志记录停止。

1 个答案:

答案 0 :(得分:1)

首先,为了清楚起见,我不会使用标志来指定如何打开/创建文件。我会用:

File.open(filename, 'a')

这是日志文件的标准模式;如果它不存在你想要创建它,如果它存在你想要追加它。

日志记录通常需要在应用程序的运行时间内多次写入同一文件。人们喜欢打开日志并保持打开状态,但如果代码在文件关闭之前崩溃或者被Ruby或操作系统刷新,则可能会出现问题。此外,Ruby和操作系统的内置缓冲可以导致文件缓冲,然后刷新,当你拖尾文件时,它将使它跳进大块,如果你是这样的话,这不是很好看东西。

您可以通过设置sync = true告诉Ruby在您写入文件时立即强制刷新:

logfile = File.open(filename, 'a')
logfile.sync = true
logfile.puts 'foo'
logfile.close

您可以使用fsync,这也会强制操作系统刷新其缓冲区。

以任何一种方式强制同步的缺点是你否定了缓冲I / O的优势。对于正常的文件写入,与文本文件一样,请不要使用sync,因为这会降低您的应用程序速度。相反,正常的I / O就像Ruby和操作系统想要的那样发生。但是对于日志记录它是可以接受的,因为日志记录应该定期发送一行,而不是大量的文本。

您可以立即flush输出,但这会多余并违反DRY原则:

logfile = File.open(filename, 'a')
logfile.puts 'foo'
logfile.flush
logfile.puts 'bar'
logfile.flush
logfile.close

close在实际关闭文件I / O之前刷新。

您可以将日志输出包装在方法中:

def log(text)
  File.open(log_file, 'a') do |logout|
    logout.puts(text)
  end
end

这将打开然后关闭日志文件,并自动刷新缓冲区,并且无需使用sync

或者您可以利用Ruby的Logger课程,让它为您完成所有工作。