Lua學習筆記 第二十一章 I O庫

2021-06-24 11:23:32 字數 4180 閱讀 5646

i/o庫為檔案操作提供了兩種不同的模型,簡單模型(****** model)和完整模型(complete

model)。簡單模型假設有乙個當前輸入檔案和乙個當前輸出檔案,它的i/o操作均作用於

這些檔案。完整模型則使用顯示的檔案控制代碼。它採用了物件導向的風格,並將所有的操作

定義為檔案控制代碼上的方法。

21.1 簡單i/o模型

簡單模型的所有操作都作用於兩個當前檔案。i/o庫將當前輸入檔案初始化為程序標準輸入,

將當前輸出檔案初始化為程序標準輸出。在執行io.read()時,就出從標出輸入中讀取一行。

函式io.input和io.output可以改變這兩個當前檔案。io.input(filename)呼叫會以唯讀模式開啟

指定檔案,並將其設為當前輸入檔案;在輸出方面,io.output也可以完成類似的工作;如果

出現錯誤,這兩個函式都會引發錯誤。如果想直接處理這些錯誤,則必須使用完整模型中的

io.open.

函式io.write可以接受任意數量的字串引數,並將它們寫入當前輸出檔案。它也可以接受數

字引數,數字引數會根據常規的轉換規則轉換為字串。如果想要控制這種轉換,則應該使

用函式string.format.

write 與 print的幾點不同:

首先,write在輸出時不會新增像製表符或回車這樣的額外字元;

其次,write使用當前輸出檔案,而print總是使用標準輸出;

最後,print會自動呼叫其引數的tostring()方法,因此它還能顯示table、函式和nil。

函式io.read從當前輸入檔案中讀取字串,它的引數決定了要讀取的資料:

"*all"      讀取整個檔案

"*line"     讀取下一行

"*number"   讀取乙個數字

讀取乙個不超過個字元的

字串呼叫io.read("*all")會讀取當前輸入檔案的所有內容,以當前位置作為開始。

如果當前位置處於檔案的末尾,或者檔案為空,那麼該呼叫會返回乙個空字串;

呼叫io.read("*line")會返回當前檔案的下一行,但並不包括換行符。當到達檔案末尾

時,該呼叫會返回nil,以表示無後續行可返回。它也是read的預設模式。建議使用

"*all"

一次性讀取整個檔案,或者按塊來讀取。如果只是為了迭代檔案中的所有行,

那麼io.lines迭代器更為合適。

for line in io.lines() do lines[#lines+1] =line end

呼叫io.read("*number")會從當前輸入檔案中讀取乙個數字。此時,read會返回乙個數字,

而不是字串。"*number"選項會忽略數字前面的所有空格,並且能處理像-3、+5.2、100

及-3.4e-23這樣的數字格式。如果無法在當前檔案位置讀到乙個數字,read會返回nil。

在呼叫read時可以指定多個選項,函式會根據每個選項引數返回相應的內容。

示例——有乙個檔案,其中每行有3個數字。現在要列印出每一行中最大的數字。

方法一,用一次read函式呼叫來讀取每行的3個數字:

while true do

local n1, n2, n3 =io.read("*number", "*number", "*number")

if not n1thenbreak end

print(math.max(n1,n2, n3))

end方法二,用"*all"來讀取整個檔案,然後用gmatch來提取其中內容:

local pat = "(%s+)%s+(%s)%s+(%s)%s+"

for n1,n2, n3 in string.gmatch(io.read("*all"),pat) do

print(math.max(tonumber(n1),tonumber(n2), tonumber(n3)))

end除以上的讀取模式外,還可以用乙個數字n作為read的引數。此時,read會試著從輸入

檔案中讀取n個字元。如果讀不到任何字元,它會返回nil。否則會返回乙個最多n個字元

的字串。

io.read(0)是乙個特殊的情況,它用於檢測是否達到了檔案末尾。如果還有資料可以讀取,

它會返回乙個空字串,否則返回nil。

21.2 完整i/o模型

完整模型是基於檔案控制代碼的,它等價於c語言中的流,表示乙個具有當前位置的開啟檔案;

要開啟乙個檔案可以使用io.open函式,它有兩個引數乙個是要開啟的檔名,另乙個是

模式字串。模式字串:

"r"表示讀取;"w"表示寫入; "a"表示追加; "b"表示開啟二進位制檔案。

open函式會返回表示檔案的新控制代碼。若發生錯誤,則返回nil,及一條錯誤訊息和乙個錯誤**。

乙個錯誤檢查的典型做法是;

local f = assert(io.open(filename, mode))

如果開啟失敗,錯誤訊息就會成為assert的第二個引數,然後assert會顯示這個資訊。

開啟檔案後,就可以用read/write方法讀寫檔案了。但要使用冒號語法,將它們作為檔案

控制代碼的方法來呼叫。--> local t = f:read("*all")  f:close()

i/o庫提供了3個預定義c語言流的控制代碼:io.stdin、io.stdout和io.stderr。這樣就可以將資訊直接

寫到錯誤流:

io.stderr:write(message)

使用者可以混合使用完整模式和簡單模式。通過不指定引數呼叫io.input(),可以得到當前

輸入檔案

的控制代碼。而通過io.input(handle),可以設定當前輸入檔案的控制代碼。

21.2.1 效能訣竅

在讀取大檔案時為了避免在行中間斷開,只需在讀乙個塊是再加上一行:

local lines, rest = f:read(bufsize, "*line")

變數rest包含了被塊所斷開的那行的剩餘部分。這樣就可以將塊與行的剩餘部分連線起來,

從而得到乙個總是起止於行邊界上的塊。

示例——統計檔案中字元數、單詞數和行數的程式:

local bufsize = 2^13 --8k

local f = io.input(arg[1])  -- 開啟輸入檔案

local cc, ic, wc = 0, 0, 0

while true do

local lines,rest = f:read(bufsize, "*line")

if not linesthen break end

if rest thenlines = lines .. rest .. "\n" end

cc = cc +#lines    -- 行數

local _, t =string.gsub(lines, "%s+", "")

wc = wc + t         --單詞數

_, t =string.gsub(lines, "\n", "\n")

lc = lc + t         --換行符數

endprint(lc, wc, cc)

21.2.3 其它檔案操作

函式tmpfile會返回乙個臨時檔案的控制代碼,這個控制代碼是以讀/寫方式開啟。這個檔案會在程式結束時自動刪除。

函式flush會將緩衝中的資料寫入檔案。它與write函式一樣,將其作為乙個函式呼叫時,

io.flush()會重新整理當前輸出檔案;而將其作為乙個方法呼叫時,f:flush()會重新整理某個特定的檔案f。

函式seek可以獲取和設定乙個檔案的當前位置。它的一半角式是f:seek(whence,offset),

其中whence引數是乙個字串,指定了如何解釋offset引數。它的有效值包括:

"set",offset解釋為相對於檔案起始的偏移量;

"cur",offset解釋為相對於當前位置的偏移量;

"end",offset解釋為相對於檔案末尾的偏移量;

函式的返回值,總是返回檔案的當前位置相對於檔案起始處的偏移位元組數。

whence引數的預設值是"cur",offset的預設值是0。因此呼叫file:seek()不會改變檔案的

當前位置,並返回當前的檔案位置。呼叫file:seek("set")會將當前位置重置為檔案的起始

處並返回0.呼叫file:seek("end")會將當前位置設定到檔案的末尾,並返回檔案的大小。

如果發生錯誤,所有這些函式都會返回nil和一條錯誤訊息。

JAVA第二十一章(小結)

1 遞迴 理解 1 方法定義中呼叫方法本身的現象 舉例 老和尚給小和尚講故事,我們學程式設計 2 遞迴的注意事項 a 要有出口,否則就是死遞迴 b 次數不能過多,否則記憶體溢位 c 構造方法不能遞迴使用 3 遞迴的案例 a 遞迴求階乘 b 兔子問題 c 遞迴輸出指定目錄下所有指定字尾名的檔案絕對路徑...

第二十一章 變換(七)

錨定規模 以下是一些螢幕截圖,顯示 從左到右 相對於左下角相對於右下角和相對於中心底部的縮放 如果您熟悉ios程式設計,則可以了解類似的anchorpoint屬性。在ios中,此屬性會影響定位和轉換中心。在xamarin.forms中,anchorx和anchory屬性僅指定轉換中心。這意味著xam...

第二十一章 變換(八)

旋轉 屬性旋轉螢幕表面上的可視元素。將 旋轉 屬性設定為以度為單位的角度 不是弧度 正角度順時針旋轉元素。您可以將 旋轉 設定為小於0或大於360的角度。實際旋轉角度是旋轉屬性模數360的值。元素圍繞相對於使用anchorx和anchory屬性指定的自身的點旋轉。planerotationdemo程...