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

File System Api

Started by augustas656, 20 July 2013 - 02:22 PM
augustas656 #1
Posted 20 July 2013 - 04:22 PM
I was making an API for pixel collision, for myself. But it didn't work because of "shell.run", I did write the script correctly. But I kept getting errors especially on the line which contained shell.run. I have checked so many times, I've even changed it a little bit. Always got an error. Then I tried using Fs API. And I typed this code:

h = fs.open("collisions","r")
h.readAll()
h.close()

In the program "collisions" I had a table which was called collisions, and in the main script I used that table, and I got an error, table expected got nil. Then I tried putting the table inside the script before h.close() and I wrote something like this collisions = solids. Then I used solids in the main script instead of collisions, but I still got table expected, got nil.

Maybe it's just a bug, that I'm not allowed to use shell.run in my script, all I wanted to do is make an API that reads code from a specified file. And that file must contain a table called the same as the file. I have tried using a different name of the table and the file, so they're not the same. It didn't work still. If you don't get my problem, can you atleast show me a (tested and working!) script of what I should use.
albrat #2
Posted 20 July 2013 - 05:29 PM
you have to put " collisions = h.readAll() "

the fs.open does not open collisions as a item in the program. it just opens it for reading. You have to assign a varible for the file to be read into for the program.

so for example : mystring = h.readAll() would grab the contents of the open file into the varible mystring…
H4X0RZ #3
Posted 20 July 2013 - 05:29 PM
EDIT:
I've got ninjad :|

If the file ONLY contains a SERIALIZED table yould could do it so:

local handle = fs.open("someFile","r") --opening the file
local content = textutils.unserialize(handle.readAll()) --reading the whole content and unserialize it
handle.close() --closing the handle
Then you can use the table :D/>/>
augustas656 #4
Posted 21 July 2013 - 06:48 AM
One problem, I used table serialization before, and I got many problems, and what I do instead is use fs.open with write mode and I write the table in an understandable way, so I can understand it easily, and so it can be read easily by script. But all I want is that the table can be read… So I'll use collisions = h.readAll()
unless it is a wrong way to do it, I don't like to use table.serialize, I actually tried using it. But even textutils wrote the table wrong. I then used the table and it got an error. So I think textutils is not what I'm looking for. So, yeah thanks…
albrat #5
Posted 21 July 2013 - 08:07 AM
you use textutils.serialize(table) to save the table to a plain text file. Then to recall it again you have to read back the data and unserialize it again.

eg.

h = fs.open("colfile", "w")
h.write = textutils.serialize(collisions)
h.close()

-- retreive the info
h = fs.open("colfile", "r")
collisions = textutils.unserialize(h.readAll())
h.close()
-- your file is now stored in collisions again. as a varible.

the first part is saving the table to a file (as plain text), the second part reads the file and converts it to a table again.

* Just re-read what you want to do. you want to be abled to edit the table and load it up…
you can use textutils serialize, then edit the table to look nicer and edit it. then reload. (the reload has to use "unserialize" otherwise the table is just stored as a normal string.)

The only other way I can think of is to make a large script that wrote lines of text then wrote each line to the file.
then to read it back line by line and insert the data into the table line by line. (alot of code).

eg.

-- this will Overwrite the file.
h = fs.open("coll", "w")
for a = 1 #table do
  h.writeLine(table[a])
end
h.writeLine("//EOF")
h.close()
-- talbe written to file
If you have sub - tables you would have to read off each table in the same way as sub tables table [a] where b is your second for loop ( eg, for b = 1,#table[a] … ) then the data in your table would be written 1 entry per line.

to re-insert the table you would have to use "h.readLine()" and have an if statement saying "if varible for the read == "//EOF" then break end" because you can not tell how large the tables should be.
** the reading back of nested tables could be a nightmare **
Yevano #6
Posted 21 July 2013 - 12:49 PM
Just to clarify, your call to shell.run wasn't working because you used it inside of an API. The shell API isn't exposed to APIs while they are being loaded.
albrat #7
Posted 21 July 2013 - 07:29 PM
local filename = "" -- default varible on API load (before function start)
local table = {} -- Default table on API load

function writer(filename, table)
  h = fs.open(filename, "w")
  h.write = textutils.serialize(table)
  h.close()
end

-- retreive the info
local filename = "" -- Default Varible on API load (before function start)

function reader(filename)
  if fs.exists(filename) then
	h = fs.open(filename, "r")
	table = textutils.unserialize(h.readAll())
	h.close()
  end
  return table
end

that written inside an API will return the table and save the table.

The write can be called by typing the APIname.writer("collisions", collisions) – that will save the table collisions to the file collisions Apiname.writer("testfile", collisions) – would save the file testfile with the table collisions in it.
The read is called by :-
collisions = APIname.reader("collisions")
This will open the file collisions and save to the table collisions.

collisions = APIname.reader("testfile")
This will open the file testfile and save to the table collisions.