Lua io.open read write seek flush setvbuf append
- 读写操作会设置同一个指针, 指针移动的距离为读写内容的长度。
p=f:seek() f:read(num)--假设文件内容够长 assert(f:seek()==p+num) f:write(str) assert(f:seek()==p+num+string.len(str))
- f:seek() (获取指针值)有f:flush() (将缓存写入文件)的功效。
- f:write() (文件写内容)后应f:flush() (将缓存写入文件),再f:read() (文件读内容)。否则,f:write()-f:read() 可能读取到意外数据(额外分配的缓存或溢出)。
- f:setvbuf() 会有未明确的影响,参考如下的 testcaseB==2 。

local f=io.tmpfile() -- 可能需要管理员权限 local fn if not f then fn='.'..os.tmpname() f=assert(io.open(fn,'w+')) end local s=0x1000--buffer size(缓存大小) local testcaseB=1 -- and 2 if testcaseB==2 then f:setvbuf('full',s) -- memory leak? 会导致内存泄露,f:read()将读取到意外的内容(require的其他脚本) end local c='abc'--content(内容),假设长度小于缓存大小 local l=string.len(c)--length(长度) assert(l<=s) f:write(c) local testcase=1 --uncomment to test -- and 2 -- and 3 local ec=string.rep('\0',s-l)--extra cache content(额外的缓存内容) if testcase==1 then local r=f:read'a' if testcaseB==1 then assert(r==ec) assert(f:seek()==s) else assert(f:seek()>=s) end else if testcase==2 then assert(f:seek()==l) elseif testcase==3 then f:flush() end assert(f:read'a'=='') assert(f:seek()==l) end f:seek'set' local r=f:read'a' if testcase==1 then if testcaseB==1 then assert(r==c..ec) else end else assert(r==c) end f:flush() f:seek'set' r=f:read'a' if testcase==1 then if testcaseB==1 then assert(r==c..ec) else end else assert(r==c) end f:close() if fn then os.remove(fn) end
- 在 io.open(..,'a[+]') append(追加)模式中,即便(通过 f:seek() )手动设置指针位置(到非末尾,如 f:seek'set' ),即便文件内容被其他过程改变,追加操作仍会在末尾。

local fn='.'..os.tmpname() local f=assert(io.open(fn,'a+')) f:write'123';f:flush() f:seek'set' f:write'456';f:flush() f:seek'set' assert(f:read'a'=='123456')--not '456' -- local f2=assert(io.open(fn,'r+')) assert(f2:seek()==0) f2:seek'end' f2:write'abc';f2:flush() f2:seek'set' assert(f2:read'a'=='123456abc') f:write'789';f:flush() f2:seek'set' assert(f2:read'a'=='123456abc789')--not '123456789' f:close() os.remove(fn)
- 以上,即便文件被其他过程( io.open(filename,'w[+]') )截断(truncate)重置,追加操作仍会在末尾。

local fn='.'..os.tmpname() local f=assert(io.open(fn,'a+')) f:write'123456';f:flush() f:seek'set' assert(f:read'a'=='123456')--not '456' -- local f2=assert(io.open(fn,'w+')) f2:seek'end' assert(f2:seek()==0)--file is truncated f2:write'abc';f2:flush() f2:seek'set' assert(f2:read'a'=='abc') f:write'789';f:flush() f2:seek'set' assert(f2:read'a'=='abc789')--not 'abc456789' f2:close() f:close() os.remove(fn)
- python - Difference between modes a, a+, w, w+, and r+ in built-in open function? - Stack Overflow
- file will be Truncated only in w/w+.
- 可以用单文件构造“管道”、输入输出缓存池。写入端仅需追加(a),读取端先读取(r),再把剩余部分(或为空)重写(w)回文件。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?