2022-03-06 17:13:34 +00:00
|
|
|
-- primitive for reading files from a file system (or, later, network)
|
2022-03-17 00:03:38 +00:00
|
|
|
-- returns an object or nil on error
|
|
|
|
-- read lines from the object using .read() with args similar to file:read()
|
|
|
|
-- read() will indicate end of file by returning nil.
|
2022-03-06 17:13:34 +00:00
|
|
|
function start_reading(fs, filename)
|
|
|
|
local infile = io.open(filename)
|
|
|
|
if infile == nil then return nil end
|
2022-03-17 00:03:38 +00:00
|
|
|
return {
|
|
|
|
read = coroutine.wrap(function(format)
|
|
|
|
while true do
|
|
|
|
if format == nil then format = '*l' end
|
|
|
|
format = coroutine.yield(infile:read(format))
|
|
|
|
end
|
|
|
|
end),
|
|
|
|
}
|
2022-03-06 17:13:34 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- primitive for writing files to a file system (or, later, network)
|
2022-03-17 00:03:38 +00:00
|
|
|
-- returns an object or nil on error
|
|
|
|
-- write to the object using .write()
|
|
|
|
-- indicate you're done writing by calling .close()
|
|
|
|
-- file will not be externally visible until .close()
|
2022-03-06 17:13:34 +00:00
|
|
|
function start_writing(fs, filename)
|
2022-03-08 03:14:02 +00:00
|
|
|
if filename == nil then
|
|
|
|
error('start_writing requires two arguments: a file-system (nil for real disk) and a filename')
|
|
|
|
end
|
|
|
|
local initial_filename = temporary_filename_in_same_volume(filename)
|
2022-03-06 17:13:34 +00:00
|
|
|
local outfile = io.open(initial_filename, 'w')
|
|
|
|
if outfile == nil then return nil end
|
2022-03-17 00:03:38 +00:00
|
|
|
return {
|
|
|
|
write = coroutine.wrap(function(x)
|
|
|
|
while true do
|
|
|
|
x = coroutine.yield(outfile:write(x))
|
|
|
|
end
|
|
|
|
end),
|
|
|
|
close = function()
|
|
|
|
outfile:close()
|
|
|
|
os.rename(initial_filename, filename)
|
|
|
|
end,
|
|
|
|
}
|
2022-03-06 17:13:34 +00:00
|
|
|
end
|
|
|
|
|
2022-03-08 03:14:02 +00:00
|
|
|
function temporary_filename_in_same_volume(filename)
|
|
|
|
-- opening in same directory will hopefully keep it on the same volume,
|
|
|
|
-- so that a future rename works
|
|
|
|
local i = 1
|
|
|
|
while true do
|
2022-03-08 05:57:11 +00:00
|
|
|
temporary_filename = 'teliva_tmp_'..filename..'_'..i
|
2022-03-08 03:14:02 +00:00
|
|
|
if io.open(temporary_filename) == nil then
|
|
|
|
-- file doesn't exist yet; create a placeholder and return it
|
|
|
|
local handle = io.open(temporary_filename, 'w')
|
|
|
|
if handle == nil then
|
|
|
|
error("this is unexpected; I can't create temporary files..")
|
|
|
|
end
|
|
|
|
handle:close()
|
|
|
|
return temporary_filename
|
|
|
|
end
|
|
|
|
i = i+1
|
|
|
|
end
|
|
|
|
end
|