Ruby 文件的輸入與輸出

2022-09-27 10:24 更新

Ruby 提供了一整套 I/O 相關(guān)的方法,在內(nèi)核(Kernel)模塊中實(shí)現(xiàn)。所有的 I/O 方法派生自 IO 類。

IO 提供了所有基礎(chǔ)的方法,比如 read、 write、 gets、 puts、 readline、 getcprintf。

本章節(jié)將講解所有 Ruby 中可用的基礎(chǔ)的 I/O 函數(shù)。如需了解更多的函數(shù),請(qǐng)查看 Ruby 的 IO 類。

puts 語(yǔ)句

在前面的章節(jié)中,您賦值給變量,然后使用 puts 語(yǔ)句打印輸出。

puts 語(yǔ)句指示程序顯示存儲(chǔ)在變量中的值。這將在每行末尾添加一個(gè)新行。

實(shí)例

#!/usr/bin/ruby

val1 = "This is variable one"
val2 = "This is variable two"
puts val1
puts val2

這將產(chǎn)生以下結(jié)果:

This is variable one
This is variable two

gets 語(yǔ)句

gets 語(yǔ)句可用于獲取來(lái)自名為 STDIN 的標(biāo)準(zhǔn)屏幕的用戶輸入。

實(shí)例

下面的代碼演示了如何使用 gets 語(yǔ)句。該代碼將提示用戶輸入一個(gè)值,該值將被存儲(chǔ)在變量 val 中,最后會(huì)被打印在 STDOUT 上。

#!/usr/bin/ruby

puts "Enter a value :"
val = gets
puts val

這將產(chǎn)生以下結(jié)果:

Enter a value :
This is entered value
This is entered value

putc 語(yǔ)句

puts 語(yǔ)句不同,puts 語(yǔ)句輸出整個(gè)字符串到屏幕上,而 putc 語(yǔ)句可用于依次輸出一個(gè)字符。

實(shí)例

下面代碼的輸出只是字符 H:

#!/usr/bin/ruby

str="Hello Ruby!"
putc str

這將產(chǎn)生以下結(jié)果:

H

print 語(yǔ)句

print 語(yǔ)句與 puts 語(yǔ)句類似。唯一的不同在于 puts 語(yǔ)句在輸出內(nèi)容后會(huì)跳到下一行,而使用 print 語(yǔ)句時(shí),光標(biāo)定位在同一行。

實(shí)例

#!/usr/bin/ruby

print "Hello World"
print "Good Morning"

這將產(chǎn)生以下結(jié)果:

Hello WorldGood Morning

打開和關(guān)閉文件

截至現(xiàn)在,您已經(jīng)讀取并寫入標(biāo)準(zhǔn)輸入和輸出。現(xiàn)在,我們將看看如何操作實(shí)際的數(shù)據(jù)文件。

File.new 方法

您可以使用 File.new 方法創(chuàng)建一個(gè) File 對(duì)象用于讀取、寫入或者讀寫,讀寫權(quán)限取決于 mode 字符串。最后,您可以使用 File.close 方法來(lái)關(guān)閉該文件。

語(yǔ)法

aFile = File.new("filename", "mode")
   # ... 處理文件
aFile.close

File.open 方法

您可以使用 File.open 方法創(chuàng)建一個(gè)新的 file 對(duì)象,并把該 file 對(duì)象賦值給文件。但是,File.openFile.new 方法之間有一點(diǎn)不同。不同點(diǎn)是 File.open 方法可與塊關(guān)聯(lián),而 File.new 方法不能。

File.open("filename", "mode") do |aFile|
   # ... process the file
end

下表列出了打開文件的不同模式:

模式 描述
r 只讀模式。文件指針被放置在文件的開頭。這是默認(rèn)模式。
r+ 讀寫模式。文件指針被放置在文件的開頭。
w 只寫模式。如果文件存在,則重寫文件。如果文件不存在,則創(chuàng)建一個(gè)新文件用于寫入。
w+ 讀寫模式。如果文件存在,則重寫已存在的文件。如果文件不存在,則創(chuàng)建一個(gè)新文件用于讀寫。
a 只寫模式。如果文件存在,則文件指針被放置在文件的末尾。也就是說,文件是追加模式。如果文件不存在,則創(chuàng)建一個(gè)新文件用于寫入。
a+ 讀寫模式。如果文件存在,則文件指針被放置在文件的末尾。也就是說,文件是追加模式。如果文件不存在,則創(chuàng)建一個(gè)新文件用于讀寫。

讀取和寫入文件

用于簡(jiǎn)單 I/O 的方法也可用于所有 file 對(duì)象。所以,gets 從標(biāo)準(zhǔn)輸入讀取一行,aFile.gets 從文件對(duì)象 aFile 讀取一行。

但是,I/O 對(duì)象提供了訪問方法的附加設(shè)置,為我們提供了便利。

sysread 方法

您可以使用方法 sysread 來(lái)讀取文件的內(nèi)容。當(dāng)使用方法 sysread 時(shí),您可以使用任意一種模式打開文件。例如:

下面是輸入文本文件:

This is a simple text file for testing purpose.

現(xiàn)在讓我們嘗試讀取這個(gè)文件:

#!/usr/bin/ruby

aFile = File.new("input.txt", "r")
if aFile
   content = aFile.sysread(20)
   puts content
else
   puts "Unable to open file!"
end

該語(yǔ)句將輸入文件的頭 20 個(gè)字符。文件指針將被放置在文件中第 21 個(gè)字符的位置。

syswrite 方法

您可以使用方法 syswrite 來(lái)向文件寫入內(nèi)容。當(dāng)使用方法 syswrite 時(shí),您需要以寫入模式打開文件。例如:

#!/usr/bin/ruby

aFile = File.new("input.txt", "r+")
if aFile
   aFile.syswrite("ABCDEF")
else
   puts "Unable to open file!"
end

該語(yǔ)句將寫入 "ABCDEF" 到文件中。

each_byte 方法

該方法屬于類 File。方法 each_byte 是個(gè)可以迭代字符串中每個(gè)字符。請(qǐng)看下面的代碼實(shí)例:

#!/usr/bin/ruby

aFile = File.new("input.txt", "r+")
if aFile
   aFile.syswrite("ABCDEF")
   aFile.rewind
   aFile.each_byte {|ch| putc ch; putc ?. }
else
   puts "Unable to open file!"
end

字符一個(gè)接著一個(gè)被傳到變量 ch,然后顯示在屏幕上,如下所示:

A.B.C.D.E.F.s. .a. .s.i.m.p.l.e. .t.e.x.t. .f.i.l.e. .f.o.r. .t.e.s.t.i.n.g. .p.u.r.p.o.s.e...

IO.readlines 方法

File 是類 IO 的一個(gè)子類。類 IO 也有一些用于操作文件的方法。

IO.readlines 是 IO 類中的一個(gè)方法。該方法逐行返回文件的內(nèi)容。下面的代碼顯示了方法 IO.readlines 的使用:

#!/usr/bin/ruby

arr = IO.readlines("input.txt")
puts arr[0]
puts arr[1]

在這段代碼中,變量 arr 是一個(gè)數(shù)組。文件 input.txt 的每一行將是數(shù)組 arr 中的一個(gè)元素。因此,arr[0] 將包含第一行,而 arr[1] 將包含文件的第二行。

IO.foreach 方法

該方法也逐行返回輸出。方法 foreach 與方法 readlines 之間不同的是,方法 foreach 與塊相關(guān)聯(lián)。但是,不像方法 readlines,方法 foreach 不是返回一個(gè)數(shù)組。例如:

#!/usr/bin/ruby

IO.foreach("input.txt"){|block| puts block}

這段代碼將把文件 test 的內(nèi)容逐行傳給變量 block,然后輸出將顯示在屏幕上。

重命名和刪除文件

您可以通過 renamedelete 方法重命名和刪除文件。

下面的實(shí)例重命名一個(gè)已存在文件 test1.txt

#!/usr/bin/ruby

# 重命名文件 test1.txt 為 test2.txt
File.rename( "test1.txt", "test2.txt" )

下面的實(shí)例刪除一個(gè)已存在文件 test2.txt

#!/usr/bin/ruby

# 刪除文件 test2.txt
File.delete("text2.txt")

文件模式與所有權(quán)

使用帶有掩碼的 chmod 方法來(lái)改變文件的模式或權(quán)限/訪問列表:

下面的實(shí)例改變一個(gè)已存在文件 test.txt 的模式為一個(gè)掩碼值:

#!/usr/bin/ruby

file = File.new( "test.txt", "w" )
file.chmod( 0755 )

下表列出了 chmod 方法中可使用的不同的掩碼:

掩碼 描述
0700 rwx 掩碼,針對(duì)所有者
0400 r ,針對(duì)所有者
0200 w ,針對(duì)所有者
0100 x ,針對(duì)所有者
0070 rwx 掩碼,針對(duì)所屬組
0040 r ,針對(duì)所屬組
0020 w ,針對(duì)所屬組
0010 x ,針對(duì)所屬組
0007 rwx 掩碼,針對(duì)其他人
0004 r ,針對(duì)其他人
0002 w ,針對(duì)其他人
0001 x ,針對(duì)其他人
4000 執(zhí)行時(shí)設(shè)置用戶 ID
2000 執(zhí)行時(shí)設(shè)置所屬組 ID
1000 保存交換文本,甚至在使用后也會(huì)保存

文件查詢

下面的命令在打開文件前檢查文件是否已存在:

#!/usr/bin/ruby

File.open("file.rb") if File::exists?( "file.rb" )

下面的命令查詢文件是否確實(shí)是一個(gè)文件:

#!/usr/bin/ruby

# 返回 true 或false
File.file?( "text.txt" ) 

下面的命令檢查給定的文件名是否是一個(gè)目錄:

#!/usr/bin/ruby

# 一個(gè)目錄
File::directory?( "/usr/local/bin" ) # => true

# 一個(gè)文件
File::directory?( "file.rb" ) # => false

下面的命令檢查文件是否可讀、可寫、可執(zhí)行:

#!/usr/bin/ruby

File.readable?( "test.txt" )   # => true
File.writable?( "test.txt" )   # => true
File.executable?( "test.txt" ) # => false

下面的命令檢查文件是否大小為零:

#!/usr/bin/ruby

File.zero?( "test.txt" )      # => true

下面的命令返回文件的大小:

#!/usr/bin/ruby

File.size?( "text.txt" )     # => 1002

下面的命令用于檢查文件的類型:

#!/usr/bin/ruby

File::ftype( "test.txt" )     # => file

ftype 方法通過返回下列中的某個(gè)值來(lái)標(biāo)識(shí)了文件的類型:file、 directory、 characterSpecial、 blockSpecial、 fifo、 link、 socket 或 unknown。

下面的命令用于檢查文件被創(chuàng)建、修改或最后訪問的時(shí)間:

#!/usr/bin/ruby

File::ctime( "test.txt" ) # => Fri May 09 10:06:37 -0700 2008
File::mtime( "text.txt" ) # => Fri May 09 10:44:44 -0700 2008
File::atime( "text.txt" ) # => Fri May 09 10:45:01 -0700 2008

Ruby 中的目錄

所有的文件都是包含在目錄中,Ruby 提供了處理文件和目錄的方式。File 類用于處理文件,Dir 類用于處理目錄。

瀏覽目錄

為了在 Ruby 程序中改變目錄,請(qǐng)使用 Dir.chdir。下面的實(shí)例改變當(dāng)前目錄為 /usr/bin。

Dir.chdir("/usr/bin")

您可以通過 Dir.pwd 查看當(dāng)前目錄:

puts Dir.pwd # 返回當(dāng)前目錄,類似 /usr/bin

您可以使用 Dir.entries 獲取指定目錄內(nèi)的文件和目錄列表:

puts Dir.entries("/usr/bin").join(' ')

Dir.entries 返回一個(gè)數(shù)組,包含指定目錄內(nèi)的所有項(xiàng)。Dir.foreach 提供了相同的功能:

Dir.foreach("/usr/bin") do |entry|
   puts entry
end

獲取目錄列表的一個(gè)更簡(jiǎn)潔的方式是通過使用 Dir 的類數(shù)組的方法:

Dir["/usr/bin/*"]

創(chuàng)建目錄

Dir.mkdir 可用于創(chuàng)建目錄:

Dir.mkdir("mynewdir")

您也可以通過 mkdir 在新目錄(不是已存在的目錄)上設(shè)置權(quán)限:

注意:掩碼 755 設(shè)置所有者(owner)、所屬組(group)、每個(gè)人(world [anyone])的權(quán)限為 rwxr-xr-x,其中 r = read 讀取,w = write 寫入,x = execute 執(zhí)行。

Dir.mkdir( "mynewdir", 755 )

刪除目錄

Dir.delete 可用于刪除目錄。Dir.unlinkDir.rmdir 執(zhí)行同樣的功能,為我們提供了便利。

Dir.delete("testdir")

創(chuàng)建文件 & 臨時(shí)目錄

臨時(shí)文件是那些在程序執(zhí)行過程中被簡(jiǎn)單地創(chuàng)建,但不會(huì)永久性存儲(chǔ)的信息。

Dir.tmpdir 提供了當(dāng)前系統(tǒng)上臨時(shí)目錄的路徑,但是該方法默認(rèn)情況下是不可用的。為了讓 Dir.tmpdir 可用,使用必需的 'tmpdir' 是必要的。

您可以把 Dir.tmpdirFile.join 一起使用,來(lái)創(chuàng)建一個(gè)獨(dú)立于平臺(tái)的臨時(shí)文件:

require 'tmpdir'
   tempfilename = File.join(Dir.tmpdir, "tingtong")
   tempfile = File.new(tempfilename, "w")
   tempfile.puts "This is a temporary file"
   tempfile.close
   File.delete(tempfilename)

這段代碼創(chuàng)建了一個(gè)臨時(shí)文件,并向其中寫入數(shù)據(jù),然后刪除文件。Ruby 的標(biāo)準(zhǔn)庫(kù)也包含了一個(gè)名為 Tempfile 的庫(kù),該庫(kù)可用于創(chuàng)建臨時(shí)文件:

require 'tempfile'
   f = Tempfile.new('tingtong')
   f.puts "Hello"
   puts f.path
   f.close

內(nèi)建函數(shù)

下面提供了 Ruby 中處理文件和目錄的內(nèi)建函數(shù)的完整列表:

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)