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

Rednet File Transfer

Started by DannySMc, 25 November 2013 - 05:00 AM
DannySMc #1
Posted 25 November 2013 - 06:00 AM
NOTE: I AM USING MINECRAFT 1.5.2, AND COMPUTERCRAFT 1.53.

Okay so I have been seeing there are a lot of rednet tutorials but they don't explain the file sharing idea very well. I more or less figured it out by myself. I am here to show you what I have learned as well as how to create a simple file sharing function.

We shall do this in steps and use an example the file we will use to transfer is called: myprogram. The computer ID's we will be using are 1 and 2 (1 being the sending computer and 2 being the receiving the computer). This will work with a wired modem and a wireless modem. It all depends on your range though (set in the config) I set my wireless range to like 9999999999999999999999 haha.

The actual concept:
+ We will have 2 computers called 1 and 2, they will both have modems (wireless) on the top.
+ All we do is make a program that will take the "myprogram" file and make it into a string (a set of characters/words),
+ Then we shall send it to the receiving computer using rednet.
+ The receiving computer will take the file and make it back into a file then save it again.

This is a very simple program indeed. This program will have no real interface and will require you to input the data needed.

Sending Computer:
Firstly you will need to get the data needed, so this is the ID of the computer you wish to send the file to, and the actual path to where the "myprogram" is.


print("File sharing program")	  -- Displays the name at the start
sleep(1)	  -- waits 1 second
print(" ")	 -- Creates an empty line
print("The path to the file you wish to send?") -- this makes a heading for the user to know what the program requires
term.write("Path: ") -- writes text saying before the data you input
-- This is good to use so users know what to write after it.
-- Some people use this to display options like Y/N, or yes/no.
filePath = tostring(read()) -- This allows a user to input text
tostring() -- makes the output be a string
read() -- makes the computer stop and allow the user to input data
tostring(read()) -- This makes the output the user writes be a string
filePath = tostring(read()) -- This assigns whatever the user writes to become the variable: filePath.
-- So if you type hello then the filePath = "hello".
--[[ NOTE: the file path will normally be the file name: test, but if it is in a folder then it uses a "/" to show the folder, so for an example the file is called hello in the folder projects, you would type(without quotes): projects/hello. ]]
--[[ Now you have to get the ID of the computer that will receive the file. but you have to make sure it is a integer, so we shall use the same kind of method like what we did with the tostring(). We shall use the following: ]]
computerID = tonumber(read()) -- assigns the input data by the user to computerID and makes sure it is a number!
print("Program will now prepare files...") -- Tells the user the data is being processed and it is making the file sendable.

Now we have the file name and the computers ID to send the data to…but the file can't be sent how it is (which is tabulated (in table format)). so now we shall do the following:
+ Convert the file into a string
+ Find the modem/type it down
+ then set up the sending function

convert file to string:

-- The filePath variable is where the file is.
local fileToSend = fs.open(filePath, "r") -- opens the file in read mode
fileContents = fileToSend.readAll() -- Makes the data in the file usable
-- Now the data can be used, we need to serialize the data so it is in string format.
strFile = textutils.serialize(fileContents)
-- Now strFile is now the string version of the file

Finds the peripheral:

-- We need to check every side for a modem to use, so we use the following code:

  for _,s in ipairs(rs.getSides()) do
    if peripheral.isPresent(s) and peripheral.getType(s) == "modem" then
	  return modemSide
    end
  end
  return false
end
-- This will return the side which the modem is on as modemSide

Sending the data:

-- before we send the data we want to tell the user that he/she needs to run the receive program on the receiving computer.
term.clear() -- clears screen
term.setCursorPos(1,1) -- sets cursor position to top left of screen
print("Please run the receive program on the receiving computer, then press 's' to send")
local event, param1 = os.pullEvent("char") -- this waits for a key to be pressed
if param1 == "s" then -- if you press the s key then
  print("Sending...") -- prints sending
  rednet.send(computerID, strFile) -- Sends file
  sleep(0.5) -- waits half a second
  print("Sent!") -- tells user it has sent
else -- if it is another key then
  print("wrong key") -- prints wrong key
end

Receiving computer:

id, msg, distance = rednet.receive() -- this covers all paramaters that are fired from rednet receive and now will halt the program till data is received.
print("Received") -- tells user it received data
print("What do you wish to name the file?") -- asks them for a name
term.write("Name: ") -- writes the name then
fileName = tostring(read()) -- allows them to write data which is stored in the variable fileName.
-- Unserializes data so it can be used as a program again
fileContents = textutils.unserialize(msg)
local fileToWrite = fs.open(fileName, "w") -- opens file in write mode
fileToWrite.write(fileContents) -- writes file contents to fileName
fileToWrite.close() -- closes handle
print("Done") -- tells the user it is done
print("File saved as: "..fileName) -- tells the user where the file is saved.

save that program as receive then run it and press "S" on the other computer and voila it will send it then go to receive file and then asks you for the name of file and it saves it for you!

Any questions: danny.smc95@gmail.com
Missed out anything? tell me!
MKlegoman357 #2
Posted 25 November 2013 - 10:52 AM
1.
sleep(1)		  -- waits 1 second

Nobody likes these pointless sleeps (although this is my opinion).

2.
filePath = tostring(read()) -- This allows a user to input text

read function returns a string so you don't need to convert it to a string.

3.
tostring() -- makes the output be a string
read() -- makes the computer stop and allow the user to input data
tostring(read()) -- This makes the output the user writes be a string
filePath = tostring(read()) -- This assigns whatever the user writes to become the variable: filePath.

All these lines are pointless. If you are trying to explain what each function does then at least comment them out.

4.
strFile = textutils.serialize(fileContents)

file.readAll() returns a string - contents of the file. You don't need to serialize it.

Also, you didn't close that file.

5.
-- We need to check every side for a modem to use, so we use the following code:

  for _,s in ipairs(rs.getSides()) do
	if peripheral.isPresent(s) and peripheral.getType(s) == "modem" then
		  return modemSide
	end
  end
  return false
end
-- This will return the side which the modem is on as modemSide

This will exit the program in any situation because:

  • If it will find a modem it will return - exit the program.
  • After the loop you return false - exit the program

Did you mean to put that code into a separate function? If so, it still wouldn't return the actual side because what you're returning is a variable called modemSide which is never set to anything. What you actually want to return is variable s. Or set the variable modemSide to s.

Also, you never open the modem in both programs.

6.
term.clear() -- clears screen
term.setCursorPos(1,1) -- sets cursor position to top left of screen

Why do you clear the screen? This program doesn't have an actual GUI to be cleared. What if I wanted to see if I've wrote the correct path to the file or what ID I told the program to use as a receiver computer ID.

7.
local event, param1 = os.pullEvent("char") -- this waits for a key to be pressed
if param1 == "s" then -- if you press the s key then

You should check for key events. What if the user accidentally turned on CAPS. He/she would press S and your program would just say 'wrong key' which would look strange.

8.
sleep(0.5) -- waits half a second

Another pointless sleep which makes Rednet look like it is slow.

9.
fileName = tostring(read()) -- allows them to write data which is stored in the variable fileName.

You don't need tostring() here too.

10.
fileContents = textutils.unserialize(msg)

You don't need textutils.unserialize().





Tips:
  • Localize your variables so things like this wouldn't happen. Also local variables are faster than global variables.
  • local myVariable = 1
  • Test your code before posting it.
  • Next time put all of your code you have written in the tutorial to one place (and even put it on pastebin) so people could see what they actually had to write along your tutorial.
Edited on 25 November 2013 - 10:00 AM