This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
tvc's profile picture

logging program

Started by tvc, 05 June 2013 - 08:36 PM
tvc #1
Posted 05 June 2013 - 10:36 PM
I need help with a program that will right to another program but i need to set which lines it writes on. I know the following code doesnt work but it will show what i mean.

X = 1
while true do
h = fs.open (test)
h.writeLineX(message)
X = X + 1
fs.close()
end

never mind found out how

http://www.computercraft.info/forums2/index.php?/topic/13284-solved-lua-writeline-deleting-file-contents/

i just need to use "a"
valithor #2
Posted 05 June 2013 - 11:36 PM
I do not believe there is a command that is capable of writing to a certain line in another program.

Also you can use

h = fs.open("test","w")
h.writeLine("message")
h.close()

to open a file write a message on the first line over writing anything that is on the first line

or

h = fs.open("test","a")
h.writeLine("message")
h.close()

this will write a message on the last line of the target program. So if you were to want to add
testing
to the last line of
this is only a test
it would show up as
this is only a test
testing

I have only started messing around with the file API yesterday and today so some of this information might be wrong.

I would suggest seeking someone else's advice if this doesn't help at all
Edited on 05 June 2013 - 09:37 PM
tvc #3
Posted 06 June 2013 - 05:41 AM
I do not believe there is a command that is capable of writing to a certain line in another program.

Also you can use

h = fs.open("test","w")
h.writeLine("message")
h.close()

to open a file write a message on the first line over writing anything that is on the first line

or

h = fs.open("test","a")
h.writeLine("message")
h.close()

this will write a message on the last line of the target program. So if you were to want to add
testing
to the last line of
this is only a test
it would show up as
this is only a test
testing

I have only started messing around with the file API yesterday and today so some of this information might be wrong.

I would suggest seeking someone else's advice if this doesn't help at all

but this only writes to one line i need to chose what lines to write to and what lines not to
theoriginalbit #4
Posted 06 June 2013 - 06:07 AM
I need help with a program that will right to another program but i need to set which lines it writes on. I know the following code doesnt work but it will show what i mean.

but this only writes to one line i need to chose what lines to write to and what lines not to
For now there is no `seek` function in CC-Lua, and there is no eta of if or when we will get it. The only way around this is to write out all the data to the file. For example if the file is storing 3 variables and you wish to update the 3rd one, you would need to open the file and write out all 3 variables to the file at once.

There is only one other way around it, and it's this (because I'm feeling generous today I'm going to be a code monkey)… make sure you read all comments as I explain what I am doing on each line


--# 3 things are required
--# file path
--# the line number to update
--# the replacement line
--# WARNING: this process is very long, and could take some time with really long files, avoid using this function as much as possible
--# instead aim to only write to a file when absolutely needed!
local function updateFile( _path, _lineNum, _newLine )
  --# a table to hold the current lines in the file
  local contents = {}
  --# open the current file
  local handle = fs.open( _path, 'r' )
  --# make sure the file could be opened
  assert( handle, "could not open file for read" )
  --# load all the lines in the file into the contents table
  for line in handle.readLine do
    table.insert(contents, line)
  end
  --# close the file
  handle.close()
  --# make sure that the line numbers in the file go up to where we are updating
  --# if we didn't do this, if we did an update on line 30, and line 30 didn't exist the file wouldn't be written properly
  for i = #contents, _lineNum do
    table.insert(contents, "")
  end
  --# replace the line in the table with the new one
  contents[_lineNum] = _newLine or ""
  --# open the file ready to write to
  handle = fs.open( _path, 'w' )
  --# make sure we could open the file
  assert( handle, "could not open file for write" )
  --# write to the file the contents table, here we use table.concat to put all the elements together instead of having to use a loop
  handle.write( table.concat(contents, '\n') )
  --# close the file
  handle.close()
  --# done, the file is updated
end


Hope this helps, any questions, just ask. :)/>
Bomb Bloke #5
Posted 06 June 2013 - 08:32 AM
A way to simplify things may be to make use of tables and textutils.serialize / textutils.unserialize.

The idea is that you dump all variables you wish to store in your file in a table. You convert that whole table to a string with "textutils.serialize()", and write it as a single line to your file.

When your program relaunches, load that one line from the file, unserialise it back into a table, and carry on making modifications to it. When you're ready to update the file again, reserialise and overwrite.

local myFile = "somefilename"
local myTable = {}

local function loadTable()
  if fs.exists(myFile) then
    local handle = fs.open(myFile,"r")
    myTable = textutils.unserialize(handle.readLine())
    handle.close()
  else
    -- The file doesn't exist, so reset all the variables in 
    -- the table to whatever default values you want to use.
    myTable = {x=1, y=4, z=12, something="whatever"}
  end
end

local function updateFile()
  local handle = fs.open(myFile,"w")
  handle.write(textutils.serialize(myTable))
  handle.close()
end

After calling "loadTable()", you can then refer to all the values you just loaded as eg "myTable.x", "myTable.y", "myTable.something" and so on (using a short table name will aid your sanity). Calling "updateFile()" would update your file with the state of all those values in one go.