Ruby 文件的输入与输出

在 Ruby 中,文件输入与输出(I/O) 是处理文件读写操作的核心功能。Ruby 提供了简单而强大的方法来操作文件,主要通过 FileIO 类实现。以下是对 Ruby 文件输入与输出的中文讲解,涵盖文件读写、操作模式、常见方法等关键内容,力求简洁清晰。


1. 基本概念

Ruby 的文件 I/O 操作主要依赖 File 类(继承自 IO 类)。可以读取文件内容、写入数据、处理文本或二进制文件。常见的操作包括打开文件、读取、写入和关闭文件。


2. 打开文件

使用 File.openFile.new 打开文件,结合块(block)是推荐方式,因为块会自动关闭文件。

基本语法

File.open("filename.txt", "mode") do |file|
  # 文件操作
end
  • filename:文件路径(如 "data.txt""./path/to/file.txt")。
  • mode:文件打开模式(见下表)。

文件模式

模式说明
"r"只读(默认),文件必须存在,从开头读取。
"w"只写,创建新文件或覆盖现有文件。
"a"追加写,文件不存在则创建,从末尾写入。
"r+"读写,文件必须存在,从开头操作。
"w+"读写,创建新文件或覆盖现有文件。
"a+"读写追加,文件不存在则创建,可读可写,从末尾写入。
"b"二进制模式(附加到其他模式,如 "rb""wb")。

示例

File.open("example.txt", "w") do |file|
  file.write("Hello, Ruby!")
end
# 创建/覆盖 example.txt,写入 "Hello, Ruby!"

3. 读取文件

Ruby 提供了多种读取文件内容的方法。

读取整个文件

  • File.read:一次性读取整个文件内容。
  content = File.read("example.txt")
  puts content  # 输出:Hello, Ruby!
  • File.readlines:读取所有行,返回数组。
  lines = File.readlines("example.txt")
  puts lines  # 输出:["Hello, Ruby!"]

逐行读取

  • each_line:逐行遍历,适合大文件。
  File.open("example.txt", "r") do |file|
    file.each_line { |line| puts line }
  end
  # 输出:Hello, Ruby!

按字节或字符读取

  • read(n):读取指定字节数。
  File.open("example.txt", "r") do |file|
    puts file.read(5)  # 输出:Hello
  end
  • gets:读取一行。
  File.open("example.txt", "r") do |file|
    puts file.gets  # 输出:Hello, Ruby!
  end

4. 写入文件

写入操作通常使用 write, puts, 或 print 方法。

  • write:写入字符串,不自动换行。
  File.open("example.txt", "w") do |file|
    file.write("Hello\n")
    file.write("Ruby")
  end
  # 文件内容:Hello\nRuby
  • puts:写入字符串并添加换行符。
  File.open("example.txt", "w") do |file|
    file.puts("Hello")
    file.puts("Ruby")
  end
  # 文件内容:
  # Hello
  # Ruby
  • 追加模式
  File.open("example.txt", "a") do |file|
    file.puts("World")
  end
  # 文件追加:World

5. 文件操作的其他方法

  • 检查文件
  puts File.exist?("example.txt")     # 输出:true(文件是否存在)
  puts File.file?("example.txt")      # 输出:true(是否为文件)
  puts File.directory?("example.txt") # 输出:false(是否为目录)
  • 文件属性
  puts File.size("example.txt")       # 输出:文件字节大小
  puts File.mtime("example.txt")      # 输出:最后修改时间
  • 删除文件
  File.delete("example.txt")  # 删除文件
  • 重命名文件
  File.rename("example.txt", "newname.txt")

6. 处理目录

Ruby 也支持目录操作,常用 Dir 类。

  • 创建目录
  Dir.mkdir("my_folder")
  • 列出目录内容
  Dir.entries("my_folder").each { |entry| puts entry }
  # 输出:. .. file1.txt file2.txt(目录中的文件和子目录)
  • 遍历目录
  Dir.glob("*.txt").each { |file| puts file }
  # 输出所有 .txt 文件

7. 异常处理

文件操作可能因文件不存在、权限不足等原因失败,建议使用 rescue 处理异常。

begin
  File.open("nonexistent.txt", "r") do |file|
    puts file.read
  end
rescue Errno::ENOENT
  puts "文件不存在!"
end
# 输出:文件不存在!

8. 二进制文件

使用 "b" 模式处理二进制文件(如图片)。

File.open("image.png", "rb") do |file|
  data = file.read
  # 处理二进制数据
end

9. 标准输入/输出

Ruby 支持从标准输入(键盘)读取和向标准输出(屏幕)写入。

  • 标准输入
  input = gets.chomp  # 读取一行,去除换行符
  puts "你输入了:#{input}"
  • 标准输出
  puts "Hello"  # 输出并换行
  print "World" # 输出不换行

10. 注意事项

  • 自动关闭:使用 File.open 带块的方式,文件会在块结束时自动关闭。
  • 手动关闭:不使用块时,需显式调用 file.close
  file = File.open("example.txt", "w")
  file.write("Hello")
  file.close
  • 编码:Ruby 默认使用 UTF-8,处理非 UTF-8 文件时需指定编码。
  File.open("example.txt", "r:UTF-8") { |f| puts f.read }
  • 性能:大文件建议逐行读取(each_line),避免一次性加载。
  • 权限:确保有读写权限,否则会抛出 Errno::EACCES

11. 示例:综合应用

module FileUtils
  def count_lines
    File.open(self, "r") { |f| f.readlines.size }
  end
end

class String
  include FileUtils
end

# 写入文件
File.open("data.txt", "w") do |file|
  file.puts("Line 1")
  file.puts("Line 2")
end

# 读取并统计行数
puts "data.txt 行数:#{"data.txt".count_lines}"  # 输出:data.txt 行数:2

# 追加内容
File.open("data.txt", "a") { |file| file.puts("Line 3") }

# 逐行读取
File.open("data.txt", "r") do |file|
  file.each_line.with_index(1) { |line, i| puts "Line #{i}: #{line}" }
end
# 输出:
# Line 1: Line 1
# Line 2: Line 2
# Line 3: Line 3

12. 总结

Ruby 的文件输入与输出通过 FileIO 类实现,操作简单且灵活。File.open 结合块是推荐方式,自动管理文件关闭。支持多种模式(读、写、追加、二进制)和丰富的方法(如 read, write, each_line)。结合异常处理和编码设置,可以安全高效地处理文件和目录操作。

如果你有具体问题或需要更详细的示例,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注