• 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('',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
    View Code
    •  在 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)
    View Code
    • 以上,即便文件被其他过程( 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)
    View Code
  • 相关阅读:
    洛谷P1908 逆序对
    codevs1690 开关灯
    洛谷P1195 口袋的天空
    洛谷P1816 忠诚
    洛谷P1536 村村通
    洛谷P3045 [USACO12FEB]牛券Cow Coupons
    洛谷P1801 黑匣子_NOI导刊2010提高(06)
    洛谷P2947 [USACO09MAR]仰望Look Up
    Android(java)学习笔记51:ScrollView用法
    Android(java)学习笔记50:通过反射获取成员变量和成员方法并且使用
  • 原文地址:https://www.cnblogs.com/RobertL/p/14191963.html
Copyright © 2020-2023  润新知