Extensions to the Lua I/O library

From Wiki
Revision as of 16:57, 8 June 2020 by Garulfo (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

<String manipulation | Table manipulation >

Overview

The module l-io.lua provides a few functions that extend the plain Lua io library with respect to file handling in general, and the reading of binary data in particular.

Note: Some of the examples contain disk write instructions. Therefore it is essential that you run context somewhere safe in your directory tree where they can't harm.

io.loaddata(filename, [textmode])

f=io.open("./text.txt", "w")
f:write("Some Text.")
f:close()

text = io.loaddata("./text.txt")
io.write(text)

A wrapper for io.open. Automatically supplies the "r" flag and handles opening and closing, returns the complete content of file filename. The optional argument textmode when non-nil|false triggers non-binary mode in certain operating systems.

io.savedata(filename, data, [separator])

text = "Some Text."

text = text:gsub(".\n", "").." and again "..text:lower()
io.savedata("./moretext.txt", text)
os.execute("cat ./moretext.txt")

sometable = { "spam", "spam", "spam", "baked beans", "spam" }
io.savedata("./moretext.txt", sometable, ",")
os.execute("cat ./moretext.txt && echo '\n'")

local function weird_write (obj)
    for i=1,10 do
        if i % 2 == 0 then
            obj:write("But cool. ")
        else
            obj:write("Weird. ")
        end
    end
    obj:write("\n")
end

io.savedata("./weirdtext.txt", weird_write)
os.execute("cat ./weirdtext.txt")

Writes data to file filename. Handles opening and closing routines automatically. data can be generic data, a list or a function. Lists are joined prior to write, using the optional separator as separator (nice for CSV output). Functions are applied to the file object.

io.exists(filename)

print(io.exists("moretext.txt") and
      "Yes, you're right (as usual)!" or
      "No, you're wasting your time, Sir!")

Tests for file filename's existence and returns a boolean accordingly.

io.size(filename)

check1 = io.size"moretext.txt"
check2 = tonumber(io.popen([[du -b moretext.txt | sed -e 's/^\([0-9]*\).*/\1/']]):read("*all"))

io.write("I counted "..check1.." bytes, and it's got "
                     ..check2.." bytes according to ‘du’.\nTherefore ")
io.write(check1 == check2 and "the size info should be reasonably accurate.\n"
                           or "something's thoroughly wrong.\n")

Returns the byte count of file filename or 0 if the file is not found.

io.noflines(object)

f = io.popen("dmesg")
local infolength=io.noflines(f)
f:close()

print("There's " .. infolength .. " lines in the kernel ring buffer.")

Returns the line count of a file object object.

io.characters(object, [group])

f = io.popen("cat ./moretext.txt")
for char1, char2 in io.characters(f,2) do
    io.write( string.format("“%s”, “%s”\n",
                            char1,
                            char2 or "") 
    )
end
f:close()

f = io.open("./moretext.txt")
for char1, char2, char3, char4 in io.characters(f,-4) do
    io.write( string.format("1: “%s”, 2: “%s”, 3: “%s”, 4: “%s”\n",
                            char1,
                            char2 or "",
                            char3 or "",
                            char4 or "") 
    )
end
f:close()

Returns an iterator over the one-byte characters of a file object object. The optional argument group accepts a signed integer which determines the number and byte order of the characters returned simultaneously. Possible values are -4, -2, 1, 2, and 4. Negative values result in the order of the characters to be reversed.

io.bytes(object, [group])

f = io.open("./moretext.txt")
for char1, char2, char3, char4 in io.bytes(f,4) do
    io.write( string.format("1: “%s”, 2: “%s”, 3: “%s”, 4: “%s”\n",
                            char1,
                            char2 or "",
                            char3 or "",
                            char4 or "") 
    )
end
f:close()

Returns an iterator over the bytes of a file object. As with io.characters, the optional argument group specifies the number and order of the bytes returned simultaneously. If there fewer bytes left at the end of a file than the absolute of group, then the remainder is ignored. Thus to process the whole file make sure that its size is a multiple of group.

io.ask(question, [default, [options]])

options = { default = "An African or European swallow?",
            other   = { "http://www.style.org/unladenswallow/", "42" } }
local someanswer = io.ask("What is the air speed velocity of an unladen swallow?", 
                   options.default,
                   options.other
)

print(someanswer == options.default and 
      "I don't know that! /He is thrown into the chasm./" or
      "OK, off you go!")

Interrupts the program flow to wait for user input. Prints the string question to stdout and returns the string given by the user. If a string default is given, it is printed in brackets and returned if the user input is empty. options has to be a list of valid input strings which are then printed in brackets as well; no other strings are accepted if options is specified.

io.readnumber(object, [offset,] count)

io.savedata("nums.txt", "\001\001\001\001\002\002\002\002\003\003\003\003")

f = io.open("nums.txt", "r")
print(io.readnumber(f, 1))
print(io.readnumber(f, 5, 1))
print(io.readnumber(f, 4))
print(io.readnumber(f, 2))
f:close()

Reads count next bytes from a file object, optionally starting at byte offset. The bytes are treated as representing a single integer which is then returned in base 10. Valid byte counts are 1, 2, 4, 8, and 12; throws an error when there are fewer bytes left from the current position to the end of file than count.

io.readstring(object, [offset,] length)

f = io.open("text.txt", "r")
str = io.readstring(f, 5, 3)
print(str)
f:close()

Returns the next length bytes from object, starting from the current position or, optionally, the byte offset.