只是为了分析我的iis日志(BONUS:碰巧知道iislog是用ASCII编码的,错误的...)
这是我的红宝石代码
1.readlines
Dir.glob("*.log").each do |filename|
File.readlines(filename,:encoding => "ASCII").each do |line|
#comment line
if line[0] == '#'
next
else
line_content = line.downcase
#just care about first one
matched_keyword = keywords.select { |e| line_content.include? e }[0]
total_count += 1 if extensions.any? { |e| line_content.include? e }
hit_count[matched_keyword] += 1 unless matched_keyword.nil?
end
end
end
Run Code Online (Sandbox Code Playgroud)
2.open
Dir.glob("*.log").each do |filename|
File.open(filename,:encoding => "ASCII").each_line do |line|
#comment line
if line[0] == '#'
next
else
line_content = line.downcase
#just care about first one
matched_keyword = keywords.select { |e| line_content.include? e }[0]
total_count += 1 if extensions.any? { |e| line_content.include? e }
hit_count[matched_keyword] += 1 unless matched_keyword.nil?
end
end
end
Run Code Online (Sandbox Code Playgroud)
"readlines"在mem中读取整个文件,为什么"打开"总是相反更快?我在Win7 Ruby1.9.3上测试了几次
Ari*_*iao 20
双方readlines并open.each_line读取该文件只有一次.Ruby将对IO对象进行缓冲,因此每次都会从磁盘读取一个块(例如64KB)数据,以最大限度地降低磁盘读取的成本.磁盘读取步骤应该没有多少时间差异.
当你调用时readlines,Ruby构造一个空数组[]并重复读取一行文件内容并将其推送到数组.最后它将返回包含文件所有行的数组.
当您调用时each_line,Ruby会读取一行文件内容并将其输出到您的逻辑中.处理完这一行后,ruby读取另一行.它重复读取行,直到文件中没有更多内容.
两种方法的区别在于readlines必须将线附加到数组.当文件很大时,Ruby可能必须复制底层数组(C级)以扩大其大小一次或多次.
挖掘源,readlines是通过io_s_readlines哪些调用来实现的rb_io_readlines.rb_io_readlines调用rb_io_getline_1获取行rb_ary_push并将结果推送到返回的数组中.
each_line是通过rb_io_each_line调用rb_io_getline_1获取行来实现的,readlines并将行生成到您的逻辑中rb_yield.
因此,没有必要将行结果存储在不断增长的数组中each_line,没有数组大小调整,复制问题.