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

如何让Ruby代码批量读取含多专辑信息的TXT文件?

解决Ruby批量读取多专辑TXT文件的问题

原代码的核心问题

  1. 重复IO操作:反复调用IO.readlines会多次读取整个文件,既低效又无法追踪读取位置。
  2. 硬编码行号:固定从指定行读取单专辑信息,无法连续解析后续专辑。
  3. 逻辑混乱:get_track和get_tracks的职责重叠,导致歌曲重复读取,无法正确对应专辑的歌曲数量。

重构后的解决方案

我们可以一次性读取文件所有内容到内存,用索引追踪读取位置,逐段解析每个专辑,直到文件内容处理完毕。

完整重构代码

# 读取单个专辑的信息,接收文件行数组和当前索引(引用传递,用于更新读取位置)
def read_single_album(lines, index_ref)
  # 读取专辑基础信息
  artist = lines[index_ref].strip
  index_ref[0] += 1
  album_name = lines[index_ref].strip
  index_ref[0] += 1
  genre_id = lines[index_ref].strip.to_i
  index_ref[0] += 1
  track_count = lines[index_ref].strip.to_i
  index_ref[0] += 1

  # 读取对应数量的歌曲
  tracks = []
  track_count.times do
    track_name = lines[index_ref].strip
    index_ref[0] += 1
    track_path = lines[index_ref].strip
    index_ref[0] += 1
    tracks << Track.new(track_name, track_path)
  end

  # 创建并返回专辑对象
  Album.new(album_name, artist, genre_id, tracks)
end

# 批量读取文件中所有专辑
def read_all_albums(file_path)
  # 一次性读取所有行,过滤空行(避免文件末尾空行干扰)
  lines = File.readlines(file_path).reject { |line| line.strip.empty? }
  index = [0] # 用数组实现引用传递,在子方法中更新索引
  albums = []

  # 循环读取直到所有行处理完毕
  while index[0] < lines.size
    albums << read_single_album(lines, index)
  end

  albums
end

代码说明

  1. 一次性读取文件:用File.readlines一次性把所有内容读入数组,避免重复IO操作,同时过滤空行防止解析错误。
  2. 索引追踪读取位置:用数组index实现引用传递(Ruby中整数是值传递,数组是引用传递),在读取单个专辑时动态更新索引,确保下一次读取从下一个专辑的起始行开始。
  3. 逐段解析专辑:
    • 先读取专辑的4行基础信息(艺术家、专辑名、流派、歌曲数)。
    • 根据歌曲数读取对应数量的歌曲(每首歌占两行:歌名+路径)。
    • 创建Track和Album对象,加入结果数组。
  4. 无硬编码行号:所有读取位置通过索引动态计算,完全兼容单专辑和多专辑的TXT文件。

使用示例

# 读取多专辑文件并处理
albums = read_all_albums("multi_albums.txt")
albums.each do |album|
  puts "艺术家: #{album.artist}"
  puts "专辑名: #{album.title}"
  puts "流派编号: #{album.genre}"
  puts "歌曲列表:"
  album.tracks.each do |track|
    puts "  - #{track.name}: #{track.location}"
  end
  puts "-------------------------"
end

适配原代码的Track/Album类

假设你的Track和Album类定义如下(如果原类结构不同,只需调整read_single_album中创建对象的参数即可):

class Track
  attr_reader :name, :location
  def initialize(name, location)
    @name = name
    @location = location
  end
end

class Album
  attr_reader :title, :artist, :genre, :tracks
  def initialize(title, artist, genre, tracks)
    @title = title
    @artist = artist
    @genre = genre
    @tracks = tracks
  end
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:10:45