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

[Question][File Handling]Working with files with multiple lines

Started by Kryptanyte, 17 February 2013 - 12:25 AM
Kryptanyte #1
Posted 17 February 2013 - 01:25 AM
Okay, so I have been playing around with the file handling API recently for a project and can't for the life of me figure out two things, before you say google it or anything, I have I still don't get this.

Question 1: When you are working with programs that have multiple lines, is it possible to read specific lines, or do I have to make a code to turn the file into a table and return specific table items.

Just as an example to help with your understanding of what I mean the file is a config file and looks something like this;


--name of project

--config option 1
configoption

--config option 2
configoption

--config option 3
configoption


etc etc.

I have been trying to read just the lines that have configoption on them. But to no prevail.

This actually leads into my second question.

Question 2: Is it possible to put a whole program into a table that can be sent via a rednet message, or as I have seen someone say before there is a limit to how big a rednet message can be, does this limit actually affect a table?

Thanks to anyone who can help, there is code avaliable but its not much. Just some failed attempts at trying to read the specific lines etc.
Goof #2
Posted 17 February 2013 - 02:57 AM
answer for first question:

Well, im using the table method, and then calling it from the specific order.
Sometimes i also make a string.find("=??=", tTabl)
and then if it finds the =??= then it knows which line it is and then returns the line number, so it could handle it.

i dont know any other methods of finding specific lines.. you could just do:


for i = 1, line_to_find-1 do
  notValueable = _fPath.readLine()
end

Question 2:

in my tests all big programs( also small) can be transferred via rednet.
just put it into a table, and send the code to the receiver which handles the message.

:D/>

i hope i could help.
LordIkol #3
Posted 17 February 2013 - 02:59 AM
Hi reon,

im not an expert in computercraft Coding but as far as i know there is no direct way to read a specific line from a file.
I solved this problem by creating a function, which as you already mentioned, puts the file into a table and then returns the line i want.
here is my code for this:


local function readSettings(l)
local file = fs.open("Settings.txt", "r")
  if file then
    log = {}
    local line = file.readLine()
    while line do
		  table.insert(log, line)
		  line = file.readLine()
    end
    file.close()
return log[l]
  end
  end

so i can just use variableX = readSettings(5) to get the setting from line 5

hope this helps you with your first question.

Greets Loki
Espen #4
Posted 17 February 2013 - 03:08 AM
I would read in the file line by line, ignoring empty lines and lines that begin with a predefined comment-prefix (like e.g. # or –).
Everytime a line doesn't get dropped due to this rule, I'd add it to a table.

That means whatever lines end up in the table all have to be assumed to be config options.

Edit: I'm assuming here that it's not really important for you to know at which location in the file a specific option is, but that you merely want to parse a file for config options.
If you then have parsed all the options and you want to overwrite a specific option, then I'd just overwrite the whole file with the complete set of options again.
This ensures that the config file will always have a proper structure after your program has parsed it successfully.
Edited on 17 February 2013 - 02:11 AM
Kryptanyte #5
Posted 17 February 2013 - 11:06 PM
Oh, I see what you mean Espen, took me a few read but do you mean once you read the line you do something like;


options = {}
line = file.readLine()

if line == sting.match("--", "(.*)") then
    
    table.insert(options, line)
    
else

end

I'm not amazing at LUA but just guessing from experience of using different things that I normally wouldn't. This is probably my best guess.

Also thank you to Lordlkol and Mikk809h for thier help. It is really useful to get some different suggestions.
theoriginalbit #6
Posted 17 February 2013 - 11:08 PM
I would read in the file line by line, ignoring empty lines and lines that begin with a predefined comment-prefix (like e.g. # or –).
Everytime a line doesn't get dropped due to this rule, I'd add it to a table.

That means whatever lines end up in the table all have to be assumed to be config options.

Edit: I'm assuming here that it's not really important for you to know at which location in the file a specific option is, but that you merely want to parse a file for config options.
If you then have parsed all the options and you want to overwrite a specific option, then I'd just overwrite the whole file with the complete set of options again.
This ensures that the config file will always have a proper structure after your program has parsed it successfully.

This is exactly what I did for CConfig. I tried a few different ways but nothing quite worked out quite as nicely as this method. I'd defs be going for something like this as long as you don't need to know what line it was on.

EDIT: To expand on the second questions answer that Mikk809h gave. Yeh you can send tables, you do it a little something like this
Sending:

-- make your table, lets say its called t
local message = textutils.serialize(t)
-- send it over rednet
Receiving:

-- receive the rednet message, lets say message is stored in a variable msg
local t = textutils.unserialize(msg)
-- use your table
Edited on 17 February 2013 - 10:13 PM
Espen #7
Posted 19 February 2013 - 12:39 AM
Spoiler
Oh, I see what you mean Espen, took me a few read but do you mean once you read the line you do something like;


options = {}
line = file.readLine()

if line == sting.match("--", "(.*)") then
	
	table.insert(options, line)
	
else

end

I'm not amazing at LUA but just guessing from experience of using different things that I normally wouldn't. This is probably my best guess.

Also thank you to Lordlkol and Mikk809h for thier help. It is really useful to get some different suggestions.

Almost. I'd probably try to match everything I don't want and only then take lines if there is no match, like so:

if not string.match(line, "^%-%-") then
  table.insert(options, line)
end
So if a line is matched, then it means it is a line that starts with – and we ignore it.
Only if it does not start with – do we add it to the table.

Btw. a very good resource IMO for regular expressions you can use in Lua:
wiki.roblox.com/index.php/String_patterns
Edited on 18 February 2013 - 11:43 PM
Kryptanyte #8
Posted 21 February 2013 - 12:08 AM
Sorry for the late reply, internet was down.

Thanks Espen, I've never actually used string.match() a lot before. Only a very basic system to check for a command at beginning of a line.

Cheers
Espen #9
Posted 21 February 2013 - 07:14 AM
@reonrules1:
No problem. :)/>
I also just noticed that I forgot about empty lines, but that should be trivial to add. ^_^/>