Lua实现文件I/O操作,你会吗?

大家好,我是袁庭新。

文件I/O(Input/Output)操作在Lua中用于与外部文件进行交互,包括读取文件中的数据和将数据写入文件。Lua提供了两种模式来进行文件操作:简单模式和完全模式。下面将详细介绍这两种模式的基本使用。

1.简单模式

1.1 简单模式介绍

简单模式提供了基本的文件操作功能,它主要通过io.open函数打开文件,然后使用返回的文件句柄进行读取和写入操作。这种模式的操作相对比较直接,适合处理简单的文件I/O需求。

简单模式的特点是,操作函数较为直观,容易理解和使用。对于小型文件的读取和写入操作比较方便。常见的使用场景是,程序的配置文件读取,我们可以使用简单模式以只读方式打开某个文件(如config.properties),逐行读取并解析这些配置参数。

1.2 函数介绍

io.open函数用于打开文件并返回一个文件描述符。如果打开失败,则返回nil加上错误消息。打开文件操作语句如下:

file = io.open(filename [, mode])

在上述语句中,filename参数表示要打开的文件的名称,可以包含路径。如果只给出文件名,默认在当前目录下查找文件。mode参数表示文件打开模式,有以下几种常见选项:

模式 描述
r 以只读方式打开文件。文件必须存在,否则会出错。
w 以写入方式打开文件。如果文件存在,会清空文件内容;如果文件不存在,则创建新文件。
a 以追加方式打开文件。如果文件存在,新写入的数据会添加在文件末尾;如果文件不存在,则创建新文件。
r+ 以读写方式打开文件。文件必须存在,读取和写入操作都可以进行。
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
a+ 文件以追加模式打开,同时允许读取文件内容。即此文件可读可写。
b 以二进制模式打开文件(可以与其他模式组合使用,如"rb"表示二进制读,"wb"表示二进制写)

io.read([format])函数表示从默认输入文件中读取数据,根据给定的模式读取不同类型的值。该函数的参数可以是下表中的一个。

模式 描述
"*l" 默认参数,读取一行,在文件尾(EOF)处返回nil。例:file.read("*l")。
"*n" 读取一个数字并返回它。例:file.read("*n")。
"*a" 从当前位置读取整个文件。例:file.read("*a")。
number 返回一个指定字符个数的字符串,或在EOF时返回nil。例:file.read(5)。

I/O简单模式操作的其他常用函数介绍见下表:

函数 含义
io.input([file]) 如果给出参数file,则将其设置为新的默认输入文件;如果没有给出参数,则返回当前的默认输入文件。
io.output([file]) 用于设置或获取默认输出文件。
io.write(...) 向默认输出文件写入数据,可以是字符串或其他可以转换成字符串的值。
io.close([file]) 关闭文件。如果没有给出参数,则关闭默认输出文件。
io.flush() 强制刷新输出缓冲区,确保所有数据都被写入文件。
io.tmpfile() 用于创建一个临时文件,并返回一个与该文件关联的文件句柄。这个临时文件在程序结束时(或者文件被显式关闭时)会自动删除,因此非常适合用于需要短暂存储数据的场景。
io.type(file) 用于检查一个文件句柄(file handle)或文件对象的类型。具体来说,它可以识别一个文件对象是以何种模式打开的,比如读模式、写模式或追加模式等。

1.3 示例演示

这里需要提前创建准备好两个文件——input.txt和output.txt。并在input.txt文件中添加如下的内容:

文件第一行内容...
文件第二行内容...
文件第三行内容...

然后创建一个名为simple_model_test.lua的脚本文件,并在该文件中添加如下的内容。

-- simple_model_test.lua文件
-- 打开文件并设置为当前输入文件
local inputFile = io.open("input.txt", "r")
io.input(inputFile)

-- 读取一行并打印
local line = io.read("*l")
print(line)

-- 关闭输入文件
io.close(inputFile)

-- 打开文件并设置为当前输出文件
local outputFile = io.open("output.txt", "w")
io.output(outputFile)

-- 写入一行
io.write("Hello, Lua!\n")

-- 关闭输出文件
io.close(outputFile)

执行以上脚本代码,程序输出结果如下。

文件第一行内容...

然后通过"cat output.txt"命令查看该文件的内容,输入结果如下所示。

Hello, Lua!

简单模式在做一些简单的文件操作时较为合适。但是在进行一些高级的文件操作的时候,简单模式就显得力不从心。例如同时读取多个文件这样的操作,使用完全模式则较为合适。

2.完全模式

2.1 完全模式介绍

在Lua中,文件I/O的完全模式是一种更为灵活和强大的文件操作方式。它提供了一系列功能,用于更精细地控制文件输入/输出流,包括对默认输入输出流的设置、高效的逐行读取以及文件内部位置的精确控制等操作,相较于简单模式,能满足更复杂的文件处理需求。

完全模式通过文件对象(由io.open()返回),可以直接调用更多函数进行复杂的文件操作,并且可以更好地控制文件访问。

2.2 函数介绍

I/O完全模式操作的常用函数介绍见下表:

函数 含义
io.open(filename [, mode]) 与简单模式中的io.open相同,打开一个文件并返回一个文件句柄。
file:read([format]) 读取文件内容。format参数与io.read相同。
file:write(...) 向文件写入数据。
file:flush() 将所有已缓冲的数据写入文件。
file:close() 关闭文件。
file:setvbuf(mode [, size]) 设置文件的缓冲方式,对于提高性能非常重要。
io.lines(filename) 用于逐行读取文件的内容,并返回一个迭代器函数。每次调用迭代器函数将返回文件中的一行内容,直到文件末尾。参数filename是一个字符串,表示要读取的文件的路径。

函数file:seek([whence, [offset]])用于对已经打开的文件进行定位操作。

  • whence参数指定定位的参考点,有以下几种选项:
    • "set":从文件开头开始定位,offset是相对于文件开头的偏移量。例如,若执行file:seek("set", 5),文件指针会被定位到文件开头后的第5个字节位置。
    • "cur":从当前位置开始定位,offset是相对于当前位置的偏移量。如果offset为正数,指针向后移动;如果为负数,指针向前移动。比如,当前文件指针在第10个字节位置,执行file:seek("cur", 3)后,指针会移动到第13个字节位置。
    • "end":从文件末尾开始定位,offset是相对于文件末尾的偏移量(偏移量为负数时表示向前移动)。例如,执行file:seek("end", -2)会将文件指针定位到文件末尾前2个字节的位置。
  • offset参数默认为0。这个函数返回文件指针的新位置(以字节为单位),如果发生错误则返回nil。

2.3 示例演示

创建一个名为complete_model_test.lua的脚本文件,并在该文件中添加如下的内容。

-- complete_model_test.lua文件
-- 打开文件进行读写操作
local file, err = io.open("example.txt", "w+")

if not file then error("无法打开文件:" .. err) end

-- 写入几行数据
file:write("Line 1\n")
file:write("Line 2\n")
file:write("Line 3\n")

-- 将文件指针设置到文件头
file:seek("set", 0)

-- 逐行读取并打印文件内容
for line in file:lines() do
  print(line)
end

-- 关闭文件
file:close()

-- 以附加模式打开文件并写入数据
local appendFile = io.open("example.txt", "a")
appendFile:write("Line 4\n")
appendFile:close()

-- 重新打开文件并读取所有数据
local readFile = io.open("example.txt", "r")
local content = readFile:read("*a")
print(content)
readFile:close()

执行以上脚本代码,程序输出结果如下。

Line 1
Line 2
Line 3
Line 1
Line 2
Line 3
Line 4

3.总结

本文主要讲述了 Lua 语言中的文件 I/O 操作,包括简单模式和完全模式。

简单模式通过 io.open 打开文件,其 mode 有 r、w、a 等多种,分别对应只读、写入、追加等操作,还可组合 b 用于二进制。io.read 能按不同格式读取数据,如 *l 读一行。此外还有 io.input 等一系列函数用于设置输入输出、写入、关闭、刷新缓冲区、创建临时文件和检查文件类型等操作,适用于小型文件和配置文件读取等简单场景。

完全模式更为强大灵活,同样用 io.open 返回文件对象后可调用更多函数。file:write 写入数据,file:flush 刷新,file:close 关闭,file:setvbuf 可设置缓冲提升性能,io.lines 逐行读取返回迭代器。file:seek 可精确控制文件指针位置,通过 whence 指定参考点,offset 设偏移量。在示例中对 example.txt 进行了创建、写入、定位、读取和追加数据等操作,能满足如同时读取多个文件等复杂的文件处理需求,相比简单模式在高级操作上更具优势。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容