This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
How to send a file over rednet
Started by turtledude01, 21 January 2013 - 10:56 AMPosted 21 January 2013 - 11:56 AM
I am trying to send files between my computers by simply haveing computer 1 run a program that sends a rednet broadcast that sais it needs the update file then it will run the update file that it grabs. That update file would then grab the rest of the files it needs from the server. I have tried many ways of doing this but i am not very good at programming (yet). Thanks to anyone that can help me!
Posted 21 January 2013 - 12:17 PM
First you open the file using the fs or io API. After reading the file send it over rednet and the receiving computer will save the file again using fs or io.
Posted 21 January 2013 - 12:29 PM
If the file is a large read it into a table and use textutils.serialize() and textutils.unserialize() to convert it to a string and back to a table again after it is sent.
Posted 21 January 2013 - 12:29 PM
Ok thanks. Ill see what i can do and if i cant get it to work correctly ill post what i come up with.
Posted 21 January 2013 - 12:31 PM
if you want some examples just search this portion of the forums it is a very common question.
Posted 21 January 2013 - 12:31 PM
I dont know how to read it into a table :(/>If the file is a large read it into a table and use textutils.serialize() and textutils.unserialize() to convert it to a string and back to a table again after it is sent.
Edit: I also have searched the forum for it but i cant figure out other peoples programs very easily.
Posted 21 January 2013 - 12:36 PM
Here is one way
local tContents = {} -- the contents table
local file = fs.open("FileNameHere", "r")
repeat
line = file.readLine()
table.insert(tContents,line)
until not line
file.close()
Posted 21 January 2013 - 12:38 PM
If the file is a large read it into a table and use textutils.serialize() and textutils.unserialize() to convert it to a string and back to a table again after it is sent.
Why on earth would you want to do that? You realize that the result of textutils.serialize() will be larger than the original file?
Posted 21 January 2013 - 12:42 PM
Well can you send a table via rednet?If the file is a large read it into a table and use textutils.serialize() and textutils.unserialize() to convert it to a string and back to a table again after it is sent.
Why on earth would you want to do that? You realize that the result of textutils.serialize() will be larger than the original file?
Posted 21 January 2013 - 12:46 PM
If you could actually help me a bit more, I still am a massive noob at programming in LUA. I cant figure out how to send it whrough rednet and rebuild the file after it is sent. Then i want to run the file again whitch i know how to do, and it would then grab more files. And i dont know how to send the file after i use the example you gave me
Posted 21 January 2013 - 12:59 PM
Try this out. It should work, but I haven't tested it.
Receive computer
This is very basic and will not handle files in directories without some modification. Just a simple example to get you going.
Spoiler
Send computer
local tContents = {}
write("Enter program to send: ")
local fileName = read() -- example "startup" to send the startup file
write("Enter Computer ID to send to: ")
local toID = tonumber(read())
local file = fs.open(fileName, "r") -- open file as read only
repeat -- read the file line by line and insert into the table
line = file.readLine()
table.insert(tContents,line)
until not line
file.close()
local sContents = textutils.serialize(tContents) --change it to a string
rednet.send(toID, fileName..","..sContents) --send it with the filename in front of it
Receive computer
local id,msg = rednet.receive()
local fileName,sContents = string.match(msg, "(%w+),(%w+)") -- split the file name from the contents
local tContents = textutils.unserialize(sContents) -- change to table
local file = fs.open(fileName,"w")
for x=1, #tContents do -- write the file line by line
file.writeLine(tContents[x])
end
file.close()
This is very basic and will not handle files in directories without some modification. Just a simple example to get you going.
Posted 21 January 2013 - 01:05 PM
Thanks, But i need to be able to have the sending computer triggered by a rednet message and send a full folder to the recieving computerTry this out. It should work, but I haven't tested it.Spoiler
Send computerlocal tContents = {} write("Enter program to send: ") local fileName = read() -- example "startup" to send the startup file write("Enter Computer ID to send to: ") local toID = tonumber(read()) local file = fs.open(fileName, "r") -- open file as read only repeat -- read the file line by line and insert into the table line = file.readLine() table.insert(tContents,line) until not line file.close() local sContents = textutils.serialize(tContents) --change it to a string rednet.send(toID, fileName..","..sContents) --send it with the filename in front of it
Receive computerlocal id,msg = rednet.receive() local fileName,sContents = string.match(msg, "(%w+),(%w+)") -- split the file name from the contents local tContents = textutils.unserialize(sContents) -- change to table local file = fs.open(fileName,"w") for x=1, #tContents do -- write the file line by line file.writeLine(tContents[x]) end file.close()
This is very basic and will not handle files in directories without some modification. Just a simple example to get you going.
Posted 21 January 2013 - 01:09 PM
Like I said a small example to get you going. No one here is going to write the entire thing for you. Will gladly help you as you run into issues. Read up on the FS, and rednet API's on the wiki page, you can read about the table and io api's here Lua 5.1 Reference Manual - contents
There are also some good tutorials here on the forums.
There are also some good tutorials here on the forums.
Posted 21 January 2013 - 01:10 PM
Well can you send a table via rednet?If the file is a large read it into a table and use textutils.serialize() and textutils.unserialize() to convert it to a string and back to a table again after it is sent.
Why on earth would you want to do that? You realize that the result of textutils.serialize() will be larger than the original file?
local h = fs.open( path, "r" )
local contents = h.readAll()
h.close()
rednet.send( id, contents )
Why is a table needed? O.oPosted 21 January 2013 - 01:12 PM
Well can you send a table via rednet?If the file is a large read it into a table and use textutils.serialize() and textutils.unserialize() to convert it to a string and back to a table again after it is sent.
Why on earth would you want to do that? You realize that the result of textutils.serialize() will be larger than the original file?Why is a table needed? O.olocal h = fs.open( path, "r" ) local contents = h.readAll() h.close() rednet.send( id, contents )
Will that keep the formatting? I've never really used readAll(). Got in the habit of using tables with reading files when I started having files edit themselves to set persistent variables.
Posted 21 January 2013 - 01:14 PM
Look into fs.list combined with fs.isDir, unless you want to create directories as well (then take a look at my file system Iterator in misc scripts in signature) and storing all the files in different table entries, then serialize the table and send. Receive, unserialize, loop through reading the table of files writing them to the computer.Thanks, But i need to be able to have the sending computer triggered by a rednet message and send a full folder to the recieving computer
Posted 21 January 2013 - 01:17 PM
Ok Thanks anyways. Ill see if i can find some way of makeing this work. I just get really frustrated really fast when i cant figure stuff out
Posted 21 January 2013 - 01:18 PM
Yes it preserves formatting. I always use read all, so that the handle is open for the shortest amount of time, then if I need a particular line I use my split string function in my Extended String Library to split it by \n to get a table of lines… Reason I do it this way is because if something happens and that file handle is still open, well it's annoying as hell!Will that keep the formatting? I've never really used readAll(). Got in the habit of using tables with reading files when I started having files edit themselves to set persistent variables.
Posted 21 January 2013 - 01:54 PM
I use:
They aren't really written to be used together, but there's no reason they couldn't be.
function rply(mssgstr)
print(mssgstr)
if dt.rcID then rednet.send(dt.rcID,mssgstr) end
end
rcvfl = function(flnm) local cntnt flnm,cntnt = flnm:match("(%S+)%s*(.*)") local hndl = fs.open(flnm,"w") hndl.writeLine(cntnt) hndl.close()
return flnm.." updated" end
srvfl = function(flnm) flnm = flnm:match("%S+") local hndl = fs.open(flnm,"r") rply(hndl.readAll()) hndl.close()
return flnm.." served" end
Simple and reliable enough for me. srvfl() takes a file name (without spaces) and opens and sends the file using rply() (my rednet message thingy). rcvfl() takes a string that is headed by a file name separated from the rest of the file by spaces, and saves the remainder of the message under the filename.They aren't really written to be used together, but there's no reason they couldn't be.
Posted 21 January 2013 - 03:52 PM
I have 1 more question, Does anyone know a good computercraft ftp program? Ive looked but i cant find any that require no input on the server