I'm trying to get lines from text file but rainmeter keep returning error code.
"Script: skintest.lua:10: attempt to call method 'lines' (a nil value)"
I've checked lots of :lines() sample but they all are not working in my environment.(same error)
What am I missing?
function Initialize()
end
function Update()
local file = ReadFile("test.txt")
local Contents = {}
local length = string.len(file)
SKIN:Bang("!SetOption MeterLabel1Value Text "..length)
if file then
for line in file:lines() do
table.insert(contents, line)
end
else
print("test.txt_is_nill")
end
length = string.len(contents)
SKIN:Bang("!SetOption MeterLabel2Value Text "..length)
end
function ReadFile(path)
path = SKIN:MakePathAbsolute(path)
local file = io.open(path)
if not file then
print('ReadFile: unable to open file at '..path)
return
end
local contents = file:read('*all')
file:close()
return contents
end
This question definitely should been posted to the Lua scripting section.
However, the posted Lua code has a few issues:
Be careful, Lua is case sensitive. This means that [color=#FF0000]C[/color]ontents and [color=#FF0000]c[/color]ontents are different variables. Initially you've declared the variable as local Contents = {}, but later you've used it as contents (eg table.insert(contents, line)). In such cases in Lua, contents isn't declared, so you can't insert nothing into it.
On the other hand, you don't have to read the content of the file twice, as you did. First you've read it in the if file then statement of the Update() function and second in the local contents = file:read('*all') line of the ReadFile function. Even if a file can be read twice, it doesn't worth to, complicating things.
A third problem is that the string.len function applies to a string, not an array (which Contents is). To get the length of Contents (an array, as I said), use instead the #Contents variable.
So, finally I rewrote a few things in your Lua script file, here is what I got:
function Initialize()
end
function Update()
local Contents, length = ReadFile('test.txt')
SKIN:Bang("!SetOption MeterLabel2Value Text "..#Contents)
SKIN:Bang("!SetOption MeterLabel1Value Text "..length)
end
function ReadFile(path)
local Contents = {}
local path = SKIN:MakePathAbsolute(path)
local file = io.open(path)
if file then
for line in file:lines() do
table.insert(Contents, line)
end
else
print("test.txt_is_nill")
end
local length = file:seek("end")
file:close()
return Contents, length
end
In addition I also removed the MeasureName=MeasureRetrieve and the Text=%1 options from the [MeterLabel1Value] meter and the Text="" option from the [MeterLabel2Value] meter. These options are not needed, because in both meters, the Text are set by the Lua script.
Please give a try to this code and let me know how it works.
Decors wrote:Still I don't get why my lines() didn't work but I gonna check carefully.
Two reasons:
As I said, you've declared the Contents variable, then you wanted to insert the lines of the file into the contents variable, which is not the same (Lua being case sensitive).
On the point where you wanted to use the lines(), you have no open file. It's true the file is open in the ReadFile function (used before those lines), but it also is closed at the end of it. You can't read the content of a closed file.