本文簡要介紹ruby語言中 IO類 的用法。
Expect 庫添加了 IO 實例方法 expect ,它的作用類似於 tcl 的 expect 擴展。
要使用此方法,您必須要求期望:
require 'expect'
請參閱 expect 了解用法。
IO 類是 Ruby 中所有輸入和輸出的基礎。一個 I/O 流可能是duplexed(即雙向),因此可能使用多個本機操作係統流。
本節中的許多示例都使用 File 類,這是 IO 的唯一標準子類。這兩個類密切相關。與 File 類一樣, Socket 庫是 IO 的子類(例如 TCPSocket 或 UDPSocket )。
Kernel#open 方法可以為這些類型的參數創建一個 IO (或 File )對象:
-
純字符串表示適合底層操作係統的文件名。
-
以
"|"開頭的字符串表示子進程。"|"之後的字符串的其餘部分作為一個進程調用,並連接了適當的輸入/輸出通道。 -
等於
"|-"的字符串將創建另一個Ruby 實例作為子進程。
IO 可以使用不同的文件模式(隻讀,write-only)和正確轉換的編碼打開。有關這些選項,請參閱 IO.new 。有關上述各種命令格式的詳細信息,請參見 Kernel#open 。
IO.popen 、 Open3 庫或 Process#spawn 也可用於通過 IO 與子進程通信。
如果可能,Ruby 將在不同的操作係統約定之間轉換路徑名。例如,在 Windows 係統上,文件名 "/gumby/ruby/test.rb" 將打開為 "\gumby\ruby\test.rb" 。在 Ruby 字符串中指定 Windows-style 文件名時,請記住轉義反斜杠:
"C:\\gumby\\ruby\\test.rb"
我們這裏的示例將使用Unix-style 正斜杠; File::ALT_SEPARATOR 可用於獲取特定於平台的分隔符。
全局常量 ARGF (也可以作為 $< 訪問)提供了一個 IO-like 流,它允許訪問命令行中提到的所有文件(如果沒有提到文件,則為 STDIN)。提供 ARGF#path 及其別名 ARGF#filename 以訪問當前正在讀取的文件的名稱。
io/控製台
io/console 擴展提供了與控製台交互的方法。可以從 IO.console 或標準輸入/輸出/錯誤 IO 對象訪問控製台。
要求 io/console 添加以下方法:
例子:
require 'io/console'
rows, columns = $stdout.winsize
puts "Your screen is #{columns} wide and #{rows} tall"
示例文件
這裏的許多示例都使用這些文件名及其對應的文件:
-
t.txt:一個 text-only 文件,假設通過以下方式存在:text = <<~EOT This is line one. This is the second line. This is the third line. EOT File.write('t.txt', text) -
t.dat:假定存在的數據文件:data = "\u9990\u9991\u9992\u9993\u9994" f = File.open('t.dat', 'wb:UTF-16') f.write(data) f.close -
t.rus:一個 Russian-language 文本文件,假設通過以下方式存在:File.write('t.rus', "\u{442 435 441 442}") -
t.tmp:假定not存在的文件。
模式
許多 IO 方法調用必須或可以為流指定 mode;模式決定如何訪問流,包括:
-
流是隻讀的、write-only 還是讀寫的。
-
流是位於其開頭還是結尾。
-
流是否將數據視為 text-only 或二進製。
-
外部和內部編碼。
指定為整數的模式
當 mode 是整數時,它必須是 File::Constants 中定義的模式的一個或多個(由按位或 (|) 組合):
-
File::RDONLY:以隻讀方式打開。 -
File::WRONLY:隻為寫入而打開。 -
File::RDWR: 打開讀寫。 -
File::APPEND:打開僅用於附加。 -
File::CREAT:如果文件不存在,則創建文件。 -
File::EXCL:如果給出File::CREAT並且文件存在,則引發異常。
例子:
File.new('t.txt', File::RDONLY)
File.new('t.tmp', File::RDWR | File::CREAT | File::EXCL)
注意: Method IO#set_encoding 不允許將模式指定為整數。
指定為字符串的模式
當mode 是字符串時,它必須以下列之一開頭:
-
'r': 隻讀流,位於開頭;流無法更改為可寫。 -
'w': Write-only 流,位於開頭;流無法更改為可讀。 -
'a': Write-only 流,位於末尾;每次寫入都附加到末尾;流無法更改為可讀。 -
'r+':讀寫流,位於開頭。 -
'w+':讀寫流,位於末尾。 -
'a+':讀寫流,位於末尾。
對於可寫文件流(即除隻讀文件之外的任何文件流),如果文件存在則將其截斷為零,如果不存在則創建該文件。
例子:
File.open('t.txt', 'r')
File.open('t.tmp', 'w')
以下任何一項都可以作為上述任何一項的後綴:
-
't':文本數據;將默認外部編碼設置為Encoding::UTF_8;在 Windows 上,啟用 EOL 和 CRLF 之間的轉換。 -
'b':二進製數據;將默認外部編碼設置為Encoding::ASCII_8BIT;在 Windows 上,抑製 EOL 和 CRLF 之間的轉換。
如果兩者都沒有給出,則流默認為文本數據。
例子:
File.open('t.txt', 'rt')
File.open('t.dat', 'rb')
以下可以後綴到上述任何可寫模式:
-
'x':如果文件不存在則創建該文件;如果文件存在則引發異常。
例子:
File.open('t.tmp', 'wx')
最後,模式字符串可以指定編碼 - 僅外部編碼或外部和內部編碼 - 通過附加一個或兩個編碼名稱,用冒號分隔:
f = File.new('t.dat', 'rb')
f.external_encoding # => #<Encoding:ASCII-8BIT>
f.internal_encoding # => nil
f = File.new('t.dat', 'rb:UTF-16')
f.external_encoding # => #<Encoding:UTF-16 (dummy)>
f.internal_encoding # => nil
f = File.new('t.dat', 'rb:UTF-16:UTF-16')
f.external_encoding # => #<Encoding:UTF-16 (dummy)>
f.internal_encoding # => #<Encoding:UTF-16>
數組 Encoding.name_list 中提供了眾多編碼名稱:
Encoding.name_list.size # => 175
Encoding.name_list.take(3) # => ["ASCII-8BIT", "UTF-8", "US-ASCII"]
編碼
設置外部編碼後,讀取的字符串在讀取時由該編碼標記,寫入的字符串在寫入時轉換為該編碼。
當同時設置外部和內部編碼時,讀取的字符串由外部編碼轉換為內部編碼,寫入的字符串由內部編碼轉換為外部編碼。有關轉碼輸入和輸出的更多詳細信息,請參閱 Encoding 。
如果外部編碼是 'BOM|UTF-8' 、 'BOM|UTF-16LE' 或 'BOM|UTF16-BE' ,Ruby 會檢查輸入文檔中的 Unicode BOM 以幫助確定編碼。對於 UTF-16 編碼,文件打開模式必須是二進製的。如果找到 BOM,則將其剝離並使用 BOM 中的外部編碼。
請注意,BOM-style 編碼選項不區分大小寫,因此“bom|utf-8”也是有效的。)
打開選項
許多 IO 方法接受可選參數 opts ,該參數確定如何打開新流:
-
:mode:流模式。 -
:flags:整數文件打開標誌;如果還給出了mode,則兩者為bitwise-ORed。 -
:external_encoding:流的外部編碼。 -
:internal_encoding:流的內部編碼。'-'是默認內部編碼的同義詞。如果值為nil,則不會發生轉換。 -
:encoding:將外部和內部編碼指定為'extern:intern'。 -
:textmode:如果為真值,則指定模式為text-only,否則為二進製。 -
:binmode:如果為真值,則指定模式為二進製,否則為text-only。 -
:autoclose:如果為真值,則指定流關閉時fd將關閉;否則它保持打開狀態。
String#encode 中提供的選項也可用,它們可以控製外部內部編碼之間的轉換。
獲取線選項
許多 IO 方法接受可選的關鍵字參數,這些參數決定如何處理流:
-
:chomp:如果true,則省略行分隔符;默認為false。
位置
IO 流具有 position ,它是流中將發生下一次讀取或寫入的非負整數偏移量(以字節為單位)。
請注意,文本流可能具有多字節字符,因此位置為 n ( bytes ) 的文本流在當前位置之前可能沒有 n characters - 可能會更少。
一個新的流最初被定位:
-
如果其模式為
'r'、'w'或'r+',則在開頭(位置0)。 -
最後(位置
self.size)如果其模式是'a'、'w+'或'a+'。
查詢位置的方法:
從流中讀取通常會改變其位置:
f = File.open('t.txt')
f.tell # => 0
f.readline # => "This is line one.\n"
f.tell # => 19
f.readline # => "This is the second line.\n"
f.tell # => 45
f.eof? # => false
f.readline # => "Here's the third line.\n"
f.eof? # => true
寫入流通常會改變其位置:
f = File.open('t.tmp', 'w')
f.tell # => 0
f.write('foo') # => 3
f.tell # => 3
f.write('bar') # => 3
f.tell # => 6
迭代流通常會改變它的位置:
f = File.open('t.txt')
f.each do |line|
p "position=#{f.pos} eof?=#{f.eof?} line=#{line}"
end
輸出:
"position=19 eof?=false line=This is line one.\n"
"position=45 eof?=false line=This is the second line.\n"
"position=70 eof?=true line=This is the third line.\n"
也可以通過某些其他方法更改位置:
電話號碼
可讀 IO 流具有 line number ,它是流中將發生下一次讀取的非負整數行號。
新流最初的行號為 0 。
方法 IO#lineno 返回行號。
從流中讀取行通常會更改其行號:
f = File.open('t.txt', 'r')
f.lineno # => 0
f.readline # => "This is line one.\n"
f.lineno # => 1
f.readline # => "This is the second line.\n"
f.lineno # => 2
f.readline # => "Here's the third line.\n"
f.lineno # => 3
f.eof? # => true
遍曆流中的行通常會更改其行號:
f = File.open('t.txt')
f.each_line do |line|
p "position=#{f.pos} eof?=#{f.eof?} line=#{line}"
end
輸出:
"position=19 eof?=false line=This is line one.\n"
"position=45 eof?=false line=This is the second line.\n"
"position=70 eof?=true line=This is the third line.\n"
相關用法
- Ruby IO.eof用法及代碼示例
- Ruby IO.read用法及代碼示例
- Ruby IO.fileno用法及代碼示例
- Ruby IO.pread用法及代碼示例
- Ruby IO.raw用法及代碼示例
- Ruby IO.readlines用法及代碼示例
- Ruby IO.to_i用法及代碼示例
- Ruby IO.self << object用法及代碼示例
- Ruby IO.tty?用法及代碼示例
- Ruby IO.close_write用法及代碼示例
- Ruby IO.write_nonblock用法及代碼示例
- Ruby IO.set_encoding_by_bom用法及代碼示例
- Ruby IO.syswrite用法及代碼示例
- Ruby IO.close_read用法及代碼示例
- Ruby IO.stat用法及代碼示例
- Ruby IO.pwrite用法及代碼示例
- Ruby IO.ungetc用法及代碼示例
- Ruby IO.noecho用法及代碼示例
- Ruby IO.new用法及代碼示例
- Ruby IO.sysopen用法及代碼示例
- Ruby IO.try_convert用法及代碼示例
- Ruby IO.write用法及代碼示例
- Ruby IO.pathconf用法及代碼示例
- Ruby IO.sysseek用法及代碼示例
- Ruby IO.closed?用法及代碼示例
注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 IO類。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。
