Ruby File 类和方法

在 Ruby 中,File 类是用于处理文件操作的核心类,继承自 IO 类,提供了丰富的功能来读写文件、管理文件属性和处理文件系统。File 类的方法分为实例方法(操作打开的文件)和类方法(直接操作文件系统)。以下是对 Ruby File 类及其方法的中文讲解,涵盖创建、读写、属性管理等关键内容,力求简洁清晰。


1. File 类概述

File 类用于操作文件系统中的文件,支持读取、写入、追加、检查文件属性等操作。常见用法是通过 File.openFile.new 打开文件,或直接调用类方法处理文件。


2. 打开文件

File.open 是最常用的方法,通常结合块(block)使用,块结束时自动关闭文件。

基本语法

File.open(filename, mode, options) do |file|
  # 文件操作
end
  • filename:文件路径(如 "data.txt""./path/to/file.txt")。
  • mode:文件打开模式(见下表)。
  • options:可选参数(如编码 :encoding => "UTF-8")。

文件模式

模式说明
"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. File 类的实例方法

实例方法用于操作已打开的文件对象。

读取方法

  • read(length = nil):读取指定字节数或整个文件内容。
  File.open("example.txt", "r") do |file|
    puts file.read(5)  # 输出:Hello
  end
  • readlines:读取所有行,返回数组。
  File.open("example.txt", "r") do |file|
    puts file.readlines  # 输出:["Hello, Ruby!"]
  end
  • gets:读取一行。
  File.open("example.txt", "r") do |file|
    puts file.gets  # 输出:Hello, Ruby!
  end
  • each_line:逐行遍历,适合大文件。
  File.open("example.txt", "r") do |file|
    file.each_line { |line| puts line }
  end
  # 输出:Hello, Ruby!

写入方法

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

定位与关闭

  • seek(offset, whence = IO::SEEK_SET):移动文件指针。
  • whenceIO::SEEK_SET(从开头)、IO::SEEK_CUR(从当前位置)、IO::SEEK_END(从末尾)。
  File.open("example.txt", "r") do |file|
    file.seek(6)  # 跳到第 6 个字节
    puts file.read  # 输出:Ruby!
  end
  • pos:获取当前文件指针位置。
  File.open("example.txt", "r") do |file|
    puts file.pos  # 输出:0
    file.read(5)
    puts file.pos  # 输出:5
  end
  • close:关闭文件(块模式下自动关闭)。
  file = File.open("example.txt", "r")
  file.close

4. File 类的类方法

类方法直接操作文件系统,无需创建 File 对象。

文件内容操作

  • File.read(filename):读取整个文件内容。
  content = File.read("example.txt")
  puts content  # 输出:Hello, Ruby!
  • File.readlines(filename):读取所有行,返回数组。
  lines = File.readlines("example.txt")
  puts lines  # 输出:["Hello, Ruby!"]
  • File.write(filename, string):写入文件(覆盖模式)。
  File.write("example.txt", "New content")

文件属性

  • File.exist?(filename):检查文件是否存在。
  puts File.exist?("example.txt")  # 输出:true
  • File.file?(filename):检查是否为文件(非目录)。
  puts File.file?("example.txt")  # 输出:true
  • File.directory?(filename):检查是否为目录。
  puts File.directory?("my_folder")  # 输出:true(如果存在)
  • File.size(filename):返回文件大小(字节)。
  puts File.size("example.txt")  # 输出:12(假设内容为 "Hello, Ruby!")
  • File.mtime(filename):返回最后修改时间。
  puts File.mtime("example.txt")  # 输出:2025-08-14 18:11:00 +0800

文件管理

  • File.delete(filename):删除文件。
  File.delete("example.txt")
  • File.rename(old_name, new_name):重命名文件。
  File.rename("example.txt", "newname.txt")
  • File.copy_stream(src, dst):复制文件内容。
  File.copy_stream("example.txt", "copy.txt")

5. 异常处理

文件操作可能因文件不存在、权限不足等抛出异常,建议使用 rescue

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

6. 二进制文件

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

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

7. 编码支持

Ruby 默认使用 UTF-8,处理非 UTF-8 文件需指定编码。

File.open("example.txt", "r:UTF-8") do |file|
  puts file.read
end
# 或通过选项
File.open("example.txt", "r", encoding: "UTF-8") { |file| puts file.read }

8. 注意事项

  • 自动关闭:使用 File.open 带块方式,文件自动关闭,推荐使用。
  • 手动关闭:不使用块时,需显式调用 file.close
  • 性能:大文件建议逐行读取(each_line),避免一次性加载(read)。
  • 权限:确保有读写权限,否则抛出 Errno::EACCES
  • 路径:注意相对路径(基于当前工作目录)和绝对路径的区别。
  • 跨平台:使用 File::SEPARATOR(或 File.join)处理路径分隔符。
  path = File.join("path", "to", "file.txt")  # 跨平台路径

9. 示例:综合应用

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

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

# 统计行数
puts "行数:#{FileUtils.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

# 检查文件属性
puts File.exist?("data.txt") ? "文件存在" : "文件不存在"  # 输出:文件存在
puts "文件大小:#{File.size("data.txt")} 字节"

10. 总结

Ruby 的 File 类提供了强大的文件操作功能,分为实例方法(如 read, write, each_line)和类方法(如 read, exist?, delete)。结合块使用 File.open 是推荐方式,可自动管理资源。注意异常处理、编码设置和性能优化(如逐行读取大文件),可以确保文件操作安全高效。

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

类似文章

发表回复

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