Reputation: 422
I'm currently working on a logging system. My problems arise when using for
loops and file writing. Here is a small example:
file = io.open("text.txt","a") --text.txt can be literally anything
for i=1,8 do
if x == true then
file:write("X is true.")
elseif y == true then
file:write("Y is true.")
end
end
Is there a way to stop the file from being written to multiple times without using file:close()
? I have a huge number of different file:write
sections, and adding file:close()
after all of them would be a massive problem.
Upvotes: 0
Views: 113
Reputation: 422
For my specific case, I've found a solution - since I just want a single option to print, and it's the last option (rather than the first, and I should've specified this), I can just set a variable to what I want my output to be and write that at the end.
log = ""
if x == 2 then
log = "X is 2."
elseif y == 2 then
log = "Y is 2."
end
file:write(log)
For the last option, I'd refer anyone to the accepted answer which should be perfect.
Upvotes: 0
Reputation: 450
If file:close()
every time is a massive problem, then this is the custom logic you need.
myFileMetatable = {} --implement all necessary file operations here
function myFileMetatable.write(self, str)
if not self.written then
self.written = true
self.f:write(str)
end
end
function myFileMetatable.close(self)
self.f:close()
end
myFile = {}
function myFile.open(filename, mode)
local t = {f = io.open(filename, mode)}
setmetatable(t, {__index = myFileMetatable})
return t
end
--now you can do
file = myFile.open("test", "w")
file:write("test")
file:write("hello")
file:write("world")
file:close() --and only "test" will be written
Note that this is probably much better than replacing file:write(str)
with something file_write(file, str)
, since you need to store somewhere the fact that the file has already been written to, which you cannot store inside the FILE*
object and using a global variable for that will break when using multiple files. That's why I wrap the FILE*
object in a table and use myFileMetatable
to implement my own methods that I will need.
However, if you need just one file at a time and don't mind the global variable then this is more efficient.
file_written = false
function file_write(file, str)
if not file_written then
file_written = true
file:write(str)
end
end
file = io.open("test", "w")
file_write(file, "test")
file_write(file, "hello")
file_write(file, "world")
file:close()
Mind that it's not as pretty as the first example and you might face a problem in the future, if you decide to expand beyond one file.
Upvotes: 2
Reputation: 560
How Egor Skriptunoff already said, I'll recommend you to write your own writing function. I'm normally using sth. like this:
local function writeFile(filePath, str)
local outfile = io.open(filePath, 'w')
outfile:write(str)
outfile:close()
end
For appending to the file easily change the mode from w
to a
.
Upvotes: 1