Ruby 文件处理

文件是用于存储数据的命名位置。例如,main.rb 是一个始终用于存储 Ruby 代码的文件。

在 Ruby 中,您可以使用内置的 File 类来读取、写入和操作文件。这个过程称为 **文件处理**。


在 Ruby 中打开文件

我们需要先打开一个文件才能对其进行任何操作。为此,我们使用 File.open 方法。让我们看一个例子

假设我们有一个名为 file1.txt 的文件。

Contents of Our File
我们的文件内容

我们可以使用 File.open 方法打开此文件

my_file = File.open("file1.txt", "r")

这里,

  • file1.txt - 我们要打开的文件名。
  • r - 以读取模式打开文件。

此代码创建一个名为 my_fileFile 对象。现在,我们可以使用此对象来处理文件。


更多关于文件打开的信息

不同的文件打开模式

Ruby 允许我们在不同的模式(读取、写入、追加等)下打开文件,根据这些模式,我们可以执行不同的文件操作。例如,

my_file = File.open("file1.txt")

在这里,我们以 **读取模式** 打开文件(我们只能读取内容,不能修改)。

注意:默认情况下,Ruby 文件以读取模式打开。因此,代码 File.open("file1.txt") 等同于 File.open("file1.txt", "r")

在 Ruby 中打开文件的不同模式

模式 描述
r 以读取模式打开文件(默认)。
w 以写入模式打开文件(创建新文件或覆盖现有文件)。
a 以追加模式打开文件(在文件末尾添加内容)。
r+ 以读写模式打开文件。
w+ 以读写模式打开文件,但会截断(清空)文件。
a+ 以读写模式打开文件。

以下是几种以不同模式打开文件的示例,

# Open a file in default mode (read)
# Equivalent to open("test.txt", "r")
my_file = File.open("test.txt")

# Open a file in write mode 
my_file = File.open("test.txt", "w")  

# Open a file in read and write mode
my_file = File.open("test.txt", "r+")
使用完整路径打开文件

我们也可以使用文件的完整路径来打开它。

file_path = "/home/user/documents/file1.txt"
my_file = File.open(file_path)

在此示例中,/home/user/documents/file1.txt 是文件 file1.txt 的完整路径,该文件位于 /home/user/documents/ 目录中。


在 Ruby 中读取文件

Ruby 提供了几种读取文件的方法。让我们看两种常见的读取方法

1. 使用 File 对象。

在这里,我们首先创建一个 File 对象,就像我们之前学到的那样。然后,我们使用 each_line 方法和 do...end 块逐行打印文件内容。例如,

# Create a File object to open a file
my_file = File.open("file1.txt")

# Read the file line by line
my_file.each_line do |line|
  puts line
end

# Close the file
my_file.close

在这里,line 是循环中的一个占位符变量。在每次迭代中,line 变量会获取文件中的一行,并在下一次迭代中移到下一行。

重要! 一旦创建了 File 对象,例如 my_file,在完成所有文件操作后必须关闭它。这会释放您的系统资源,并确保数据安全地写入磁盘。


2. 使用块(自动关闭文件).

您也可以使用一个块,在定义循环本身时打开文件。例如,

File.open("file1.txt", "r") { |file| puts file.read }

在这里,file 是一个占位符变量,代表我们刚刚打开的 File 对象。然后,我们使用占位符的 read 方法来读取文件。

重要! 此代码将文件的全部内容加载到内存中,作为 **一个字符串**。因此,虽然此代码易于阅读,但它 **不适合** 大文件。

相反,您可以使用 each_line 逐行读取文件

File.open("file1.txt", "r") do |file|
  file.each_line { |line| puts line }
end

在此代码的每次迭代中,line 占位符会存储文件的单行,并在下一次迭代中移到下一行。

注意:使用块更安全,并且在 Ruby 中更符合习惯,因为文件会在块完成后自动关闭。


其他文件读取方法

除了 read 方法(它读取整个文件)之外,您还可以根据需要使用以下方法

  • readline - 读取文件的一行。
  • readlines - 将所有行读取到一个数组中,每一行都是数组中的一个元素。

让我们使用这些方法来读取以下文件

Contents of Our File
我们的文件内容

1. 使用 readline 方法。

my_file = File.open("file1.txt", "r")

puts my_file.readline    # Output: This is a test file.
puts my_file.readline    # Output: Hello from test file.

在这里,readline 读取文件的单行并将文件指针移到下一行。因此,当您再次使用 readline 时,它会打印下一行。

2. 使用 readlines 方法。

my_file = File.open("file1.txt", "r")

puts my_file.readlines

# Output:
# This is a test file.
# Hello from test file.

正如您所见,readlines 读取了整个文件。

read 和 readlines 之间的区别。

read 方法将文件内容作为 **一个字符串** 返回。例如,readfile1.txt 的内容返回为

# String returned after using 'read' for file1.txt
"This is a test file.\nHello from test file."

另一方面,readlines 方法返回一个数组,其中每一行都是数组中的一个元素。例如,readlinesfile1.txt 的内容返回为

# Array returned after using 'readlines' for file1.txt
["This is a test file.", "Hello from test file."]

向文件写入内容

要向文件写入内容,我们在 "w"(写入)模式下打开文件,并在 do 循环中使用 write 方法。让我们用我们的 file1.txt 文件试试

File.open("file1.txt", "w") do |file|
  file.write("My text file!")
end

此代码创建(或覆盖)file1.txt,并将字符串 "My text file!" 写入文件。

重要! "w" 会覆盖现有文件。

由于 file1.txt 已存在,所有先前的内容将被 write 方法内的文本内容替换。因此,我们的文件现在看起来像这样

"w" 会覆盖现有文件

向文件追加内容

我们在 "a"(追加)模式下打开文件,以将文本添加到现有文件的末尾。让我们看看如何使用我们原始的 file1.txt 文件来实现这一点

Original Contents of the File
文件的原始内容

然后,我们可以使用追加模式添加句子 "My text file!",如下所示

File.open("file1.txt", "a") do |file|
  file.puts("My text file!")
end

在这里,file.puts 会将新内容添加到文件(并在末尾添加一个新行),而不会擦除原始内容。因此,我们的文件现在看起来像这样

Appended File Contents
追加后的文件内容

您可以看到它将新文本附加到了原始文件内容的末尾。

为了解决这个问题,在追加文本的开头添加一个换行符 "\n"

File.open("file1.txt", "a") do |file|
  file.puts("\nMy text file!")
end

正如您所见,写入 "\nMy text file!" 将我们追加的文本移到了下一行

Appended File Contents with Newline
追加了换行符的文件内容

检查文件是否存在

我们可以使用 exist? 方法来检查文件是否存在

if File.exist?("file1.txt")
  puts "File found!"
else
  puts "File not found."
end
使用异常处理来处理文件操作中可能出现的问题。

与上面的简单 if...else 语句不同,您可以使用 **异常处理** 来使您的代码更健壮、更防错。例如,

# Try to open the file inside the begin statement
begin
  File.open("file1.txt") do |file|
    puts "File found!"
  end

# If file doesn't exist, print a message
rescue Errno::ENOENT
  puts "File not found."

# Code to execute if there are any other errors
rescue StandardError => e
  puts "An error occurred: #{e.message}"
end

这里,

  • File.open("file1.txt") 尝试以读取模式打开文件。
  • 如果文件不存在,Ruby 会引发 Errno::ENOENT,我们会捕获它并响应消息 "File not found."
  • 第二个 rescue 块捕获任何其他意外错误。

请注意,begin...rescue 语句消除了使用 exists? 方法的需要。如果无法打开文件,代码将引发错误(由 rescue 语句处理)。

如需了解更多信息,请访问 Ruby 异常处理


重命名和删除文件

重命名文件

我们可以使用 rename 方法重命名文件

File.rename("file1.txt", "renamed_file.txt")

在这里,我们将 file1.txt 重命名为 renamed_file.txt

删除文件

我们可以使用 delete 方法删除文件

File.delete("file1.txt")

在这里,我们使用 delete 方法删除了 file1.txt


Ruby 文件处理中需要记住的事情

  • 始终使用 close 方法关闭 File 对象(除非您使用块,块会在操作完成后自动关闭文件)。
  • 使用块 配合 File.open 以获得更安全、更简洁的代码。
  • 使用异常处理(例如,文件未找到)配合 begin...rescue 来实现健壮的应用程序。
  • 选择正确的模式以避免意外删除或覆盖数据(例如,使用追加模式 "a" 而不是写入模式 "w" 来向现有文件添加新内容)。
你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战