I am trying to write something to a file using a function then read it using another function. Here is my code:-
local getContent = function(fName)
local file = io.open(fName, "r")
if file == nil then
print("Could not open the file")
return
end
local fData = file:read("*all")
print("File data:-\n" .. fData)
file:close()
end
local writeToFile = function(fName, fWrite)
local file = io.open(fName, "r+")
if file == nil then
print("Could not open the file")
return
end
print("Content: " .. file:read("*all")) -- When I use r+ and read the file it acts as append mode and adds the file to the next line
-- If I am not reading the file then it acts as write mode and truncates the file
file:write(fWrite)
-- When I try to read file here then it throws an error
file:close()
end
local fileName = "lua-file.txt"
writeToFile(fileName, "My name is Dante\n")
getContent(fileName)
Q1. When I try to read the file in modes with "+" at end like "r+" and after writing to them inside the writeToFile() then the terminal throws an error. I can read the file before writing to it. How can I solve this?
Q2. "w+" and "a+" behave as I expect them to. "w+" truncates the file before writing and "a+" appends data to it at the last line. "r+" depends if am reading the file before writing to it then it appends the data if I am not reading before writing then it truncates the file before writing.
Q3. When I am not reading the file before writing i.e. remove line 8 from writeToFile() function
print("Content: " .. file:read("*a")) then it truncates the data as I said above but if I change to append+ mode run the file then change back to read+ then it doesn't write to the file at all.
To write and read to and from an open file:
Whenever you successfully perform any read or write operation on a file - regardless of the mode the file was opened with - the file position indicator for the file will have changed.
For
r+(read extended), the file position indicator is initially set to the start of the file, and both reading and writing are allowed1. Starting by reading the entire file then places the indicator at the end of the file. Immediately following this with a write operation will then appear as an append, and the file position indicator will still be at the end of the file. Attempting to read at this point will not return any data from the file - you must first seek to a position with data.This can be done with
file:seek. For example,places the file position indicator at the start of the file.
1. Note that because Lua's I/O is a very thin wrapper around C's I/O, we should refer to documentation on
fopento learn the order in which operations may be performed on a file opened for both reading (input) and writing (output):From this we can see that a call to
file:writeimmediately followed by a callfile:readis not actually allowed. You must callfile:seek(orfile:flush) in-between writing and reading.If you want to open your file a second time, in order to read what you have just written, you must first commit these changes to the file with
file:flush(orfile:close), as otherwise the data is surely buffered (see alsofile:setvbuf).Aside: you describe immediately writing to a file after opening it with
r+mode as having truncated the file, but what is actually happening is the new data is overwriting the previous data. Only when the new data is at least equal in length to the previous data does it appear as though truncation occurred, otherwise the 'tail' of the previous data will remain.