You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby中如何低成本获取调用文件的总行数?

Ruby 获取调用文件总行数的低成本方案

Ruby没有内置直接获取文件总行数的API,但可以通过缓存+高效行统计的方式实现低成本需求,完美适配你的调试工具场景:

核心实现思路

直接每次读取文件统计行数确实开销大,但同一个文件在调试过程中不会频繁变动,用缓存存储已统计过的文件行数,就能避免重复IO操作。同时用高效的行统计方法,减少内存占用。

基础缓存版实现

# 模块级缓存,存储文件路径对应的总行数
@@line_count_cache = {}

def get_total_lines(file_path)
  # 优先返回缓存结果
  return @@line_count_cache[file_path] if @@line_count_cache.key?(file_path)

  # 用File.foreach逐行统计,不加载整个文件到内存
  line_count = 0
  File.foreach(file_path) { line_count += 1 }
  
  # 写入缓存
  @@line_count_cache[file_path] = line_count
  line_count
rescue Errno::ENOENT, Errno::EACCES
  # 处理文件不存在或无权限的异常,返回nil
  nil
end

结合你的调试代码使用

把这个方法和你现有获取行号的代码结合,就能输出3/122格式的内容:

loc = caller_locations(1, 1).first
current_line = loc.lineno
total_lines = get_total_lines(loc.path)

# 输出结果,兼容文件无法读取的情况
puts total_lines ? "#{current_line}/#{total_lines}" : current_line.to_s

进阶:支持文件更新的缓存版

如果调试过程中需要实时获取修改后的文件行数,可以在缓存中同时存储文件的修改时间,每次调用时检查文件是否更新:

@@line_count_cache = {}

def get_total_lines(file_path)
  if @@line_count_cache.key?(file_path)
    cached_count, cached_mtime = @@line_count_cache[file_path]
    return cached_count if File.mtime(file_path) == cached_mtime
  end

  line_count = 0
  File.foreach(file_path) { line_count += 1 }
  @@line_count_cache[file_path] = [line_count, File.mtime(file_path)]
  line_count
rescue Errno::ENOENT, Errno::EACCES
  nil
end

为什么用File.foreach?

相比File.read(file_path).lines.size,File.foreach会逐行读取文件并立即处理,不会把整个文件内容加载到内存,对于大文件来说内存友好得多,统计效率也更高。

内容的提问来源于stack exchange,提问作者tscheingeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:45:13