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

fs.open help

Started by cant_delete_account, 23 April 2012 - 09:27 PM
cant_delete_account #1
Posted 23 April 2012 - 11:27 PM
So, I'm working on an RPG, and I want it to save the location of the player to a text file, but I need to clear the first line, and I also need to read a certain line, so first of all, is there a way to read a certain line, like sFile.readLine(linenumber)? I think that already exists, but can you read a certain line with it? Also, is there a way to clear a certain line of the file?

Thanks in advance,
thesbros
P.S: I'm not (too) good with the fs API. XD
LipJ #2
Posted 23 April 2012 - 11:58 PM
I struggled with this also. I found the easyest way to read a certain line was to just read all of them before selecting one.

–reading the file
Fileh = Fs.open(path, r)
Line1 = Fileh.readLine()
Line2 = Fileh.readLine()
Line3 = Fileh.readLine()
Line4 = Fileh.readLine()
Fileh.close()

–changing line one
Line1w = newPlayerPos()

–writeing the file back with changed line one
Fileh2 = Fs.open(path, w)
Line1w = Fileh.writeLine()
Line2 = Fileh.writeLine()
Line3 = Fileh.writeLine()
Line4 = Fileh.writeLine()
Fileh.close()

It's untested so might need some syntax work but that's roughly how I did it.
OminousPenguin #3
Posted 24 April 2012 - 12:17 AM
LipJ is right. The only way is to read the file line by line.

Can you not just keep the data in a table and then write it to file when the user closes the program? That way there is no need to keep reading and writing the file.

If not, then in your loop you can read a line and write it straight back out until you get to where you want to make a change or whatever. Then you can read the rest of the file in one go and write it all in one go back to the file.
Luanub #4
Posted 24 April 2012 - 12:44 AM
If you fs.open that is the only option. fs.open is not the only option however..

do this..

file = io.open("filname", r )
contents = file:read("*a") -- *a reads the whole file, *n for number, *l for line
file:close()
MysticT #5
Posted 24 April 2012 - 01:27 AM
If you fs.open that is the only option. fs.open is not the only option however..

do this..

file = io.open("filname", r )
contents = file:read("*a") -- *a reads the whole file, *n for number, *l for line
file:close()
file.readAll() does the same, and it would be harder to search for specific lines since you should have to search for newlines in the string. The best way is to read line by line and save it to a table:

function readLines(sPath)
  local file = fs.open(sPath, "r")
  if file then
	local tLines = {}
	local sLine = file.readLine()
	while sLine do
	  table.insert(tLines, sLine)
	  sLine = file.readLine()
	end
	file.close()
	return tLines
  end
end

function writeLines(tLines, sPath)
  local file = fs.open(sPath, "w")
  if file then
	for _, line in ipairs(tLines) do
	  file.writeLine(line)
	end
	file.close()
  end
end
Luanub #6
Posted 24 April 2012 - 01:34 AM
If you fs.open that is the only option. fs.open is not the only option however..

do this..

file = io.open("filname", r )
contents = file:read("*a") -- *a reads the whole file, *n for number, *l for line
file:close()
file.readAll() does the same, and it would be harder to search for specific lines since you should have to search for newlines in the string. The best way is to read line by line and save it to a table:

function readLines(sPath)
  local file = fs.open(sPath, "r")
  if file then
	local tLines = {}
	local sLine = file.readLine()
	while sLine do
	  table.insert(tLines, sLine)
	  sLine = file.readLine()
	end
	file.close()
	return tLines
  end
end

function writeLines(tLines, sPath)
  local file = fs.open(sPath, "w")
  if file then
	for _, line in ipairs(tLines) do
	  file.writeLine(line)
	end
	file.close()
  end
end

Indeed tables are the best way. I like to use CSV's read the whole file into a string then split the string into a table using the ,'s as the separator.
Turtle #7
Posted 24 April 2012 - 09:57 AM
You could technically repeat loading lines, until it hits a special end line, (in most cases, either an empty line, or nil)