Jump to content




[File Handling Error]Receiving and writing files


  • You cannot reply to this topic
10 replies to this topic

#1 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 01 March 2013 - 08:47 PM

I'm currently attempting to develop a update system for a project on a server I am an admin on, its pretty basic although it might be confusing, I have actually confused myself with the reading of the files by putting tables in tables I think? I'm not too sure and this could all because I'm being stupid and doing something that isn't possible or doing it wrong, not sure but here's the error;

<filename>:51: attempt to concatenate string and nil

Here's the programs;


Receiver Program
Spoiler

Sender Program (Aka where all the files are stored)
Spoiler

Sorry for the messy weird code that you may have issues reading etc, but there's also an odd bug that I noted, in the receiving program, for debug reasons, I added a clear and a print in a couple of places to tell me where its at.

Well first off, the term.clear() after its meant to receive how many programs will not fire, not sure whats going on there, then after that the line "print("File Name: "..fileName)" prints the number.

This is quite possibly the weirdest code that I have ever made, it also thinks that when you swap out the 8 in the for statement for "fileNumber" it says something like the for statement has no max amount of times it can repeat.

To anyone who can help, thank you and I would be amazed if anyone could figure this out.... It wouldn't just be my emulator would it? o.O

Cheers

Krypt

#2 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 01 March 2013 - 10:10 PM

I'm not too sure what the loops are doing, and why you are pulling events several times in the loops and such.

Tables for the messages are defs the easiest way to do this. the basic concepts are right too but you just have some mistakes that are causing some issues.

I was feeling extremely bored so I put this together its based off yours, its only basic, it can only do one file at a time, but if you look in the client you can see that you are able to still do multiple, just have to be separate requests (note people don't always do this, make solutions, we aren't code monkeys)

Server
Client

here is the outcome of the program: http://puu.sh/2ac4B

if you have any questions about how the code works or such just ask.

#3 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 02 March 2013 - 01:08 AM

Well this was originally developed as a single file sender, but was intended to be a full OS updater. I'm trying to make it so you can pass it two tables, one with the locations of the files, the second with names of the files so the receiver knows what to save it as, this is what the loops everywhere are for. I'm probably a bit out of it but I'll try to explain it.

I have multiple pull events because I am receiving 3 things, 1st thing; how many files there are. 2nd thing; the name of the program to save to. 3rd thing; the actual program. This is due to the fact that this program is designed to basically be standalone on the server. So say I implement this into an OS, the main OS programs will check for an update, if available it will download the new updater and the updater will then download the files that have been updated. However say there was a bug with one version of the OS, say I created a totally new file, the clients don't know what the file is called, so I send the whole lot to the client from the server standalone. Also helps as the server/s that handle the updating are the mainframe for the whole network.

I have looked at your program, and as you can see from my above explanation, its not exactly what I am trying to however that is exactly what you would want to put in a cloud file server, have it setup so that the server sends the information of each directory and if the client wants to download a file, it requests it.

Also to;

Quote


(note people don't always do this, make solutions, we aren't code monkeys)


I know and I do thank you for creating such a program that I will possibly understand in a few months, maybe. xD

#4 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 02 March 2013 - 01:23 AM

View PostKryptanyte, on 02 March 2013 - 01:08 AM, said:

Well this was originally developed as a single file sender, but was intended to be a full OS updater. I'm trying to make it so you can pass it two tables, one with the locations of the files, the second with names of the files so the receiver knows what to save it as, this is what the loops everywhere are for. I'm probably a bit out of it but I'll try to explain it.

I have multiple pull events because I am receiving 3 things, 1st thing; how many files there are. 2nd thing; the name of the program to save to. 3rd thing; the actual program. This is due to the fact that this program is designed to basically be standalone on the server. So say I implement this into an OS, the main OS programs will check for an update, if available it will download the new updater and the updater will then download the files that have been updated. However say there was a bug with one version of the OS, say I created a totally new file, the clients don't know what the file is called, so I send the whole lot to the client from the server standalone. Also helps as the server/s that handle the updating are the mainframe for the whole network.
Ok I understand, can be achieved better than relying on getting 3 messages in the correct order. the easiest thing would be to do something like this on the server:
local filesToSend = {}
for i = 1, #filesList do -- files list here is a list of all your file paths
  local filePath = filesList[i]
  local handle = fs.open( filePath, 'r' )
  if handle then
    filesToSend[ filePath ] = handle.readAll()
    handle.close()
  end
end

rednet.send( <id>, textutils.serialize( filesToSend ) ) -- make the files to send table a string and send it

then on the receiving end
-- get the message in
msg = textutils.unserialize(msg) -- change it back to a table
for k,v in pairs( msg ) do -- lets go through the table getting the key (paths) and value (contents) from it
  local h = fs.open(k, 'w')
  if h then
    h.write( v )
    h.close()
  else
    printError("Cannot update file "..k )
  end
end
Or something to that effect. I typed this out here in the editor so I did not test this version unlike my previous one, but the logic should be sound.

View PostKryptanyte, on 02 March 2013 - 01:08 AM, said:

I know and I do thank you for creating such a program that I will possibly understand in a few months, maybe. xD
My solution defs isn't that different to yours.

#5 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 02 March 2013 - 01:36 AM

Yeah, I read the first line of your post and thought, should of put it in one table, xD. I tend to do that a lot, I don't know why.

I see how you did it there, the only thing is when the server is getting all the programs, is there a way to make it so that the filepath saved into the table to send is rather a custom filepath? Instead of just where it got the actual program from. For example, say the updates were saved in directory "Updates" and the save directory was "Main Files" or "Configs" or something.

How exactly would to you about doing that? (I know of tables, I know you can do crazy stuff like this, I just don't know how to do. Also sorry for asking this here, my internet is capped and is slow. This is pretty much the only site that doesn't take an hour to load...)

#6 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 02 March 2013 - 01:43 AM

You could have it do
for k,v in pairs(filesList) do
  -- then open and read k, and v is the path that it goes into, then the rest is the same as previous
end
then your table would be say
filesList = {
  ["server/path"] = "/some/install/path"
}


Tables info in the PIL hopefully you can load it

#7 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 02 March 2013 - 01:46 AM

Thank you very much for your help dude (Never EVER thought I would say such a thing to an aussie.) you are an extremely helpful person

#8 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 02 March 2013 - 01:55 AM

your welcome, anytime ... watch your mouth there mate talking down about us aussies, might not help next time if thats your attitude. :P damn kiwis.

#9 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 02 March 2013 - 01:59 AM

View PostTheOriginalBIT, on 02 March 2013 - 01:55 AM, said:

your welcome, anytime ... watch your mouth there mate talking down about us aussies, might not help next time if thats your attitude. :P damn kiwis.

Thats ok, seems that we are in a stalemate anyway. All we ever seem to do is sit across the street from each other yelling insults xD

*EDIT*

Just opened up that code for storing the programs, this is what I have made with it, just the sending side;

Spoiler


Don't mind the names of the function etc, I just deleted most of the original code. I'm picking up an error when its trying to kick start the for loop. It says; bad argument : table expected, got nil. Sorry its almost 3am, am I missing something here? or is it a genuine problem with the syntax, as you said, you didn't test it.

#10 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 02 March 2013 - 02:42 AM

the for loop is looking for filesList
the table name is progNames

also table declarations should be above where they are used

side note: I know its almost 3am, we are only 2hrs behind.

#11 Kryptanyte

  • Members
  • 95 posts
  • LocationNew Zealand

Posted 02 March 2013 - 11:51 AM

The fact the table is where it is shouldn't matter as it's being called in a function. or does it still have to do this?

*EDIT*

I fixed it somewhat, when on the server side program, you need to change the line

local filePath = filesList[i]

to

local filePath = k


So that was my bad, also need to figure out the custom directory save in the table. At the moment, it just saves to the main directory. Working on this now

*EDIT 2*

Well, figured it out in 5 mins, when reading the files on serverside change the readAll() line to

filesToSend[ v ] = handle.readAll()


Updated code;

Server
Spoiler

Client Program
Spoiler

To anyone who uses these codes please give TheOriginalBit and myself credit, mostly TheOriginalBit though.

Cheers

Krypt





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users