Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add high-level Copy and Move commands #37

Closed
natiki opened this issue Jan 26, 2017 · 17 comments
Closed

Add high-level Copy and Move commands #37

natiki opened this issue Jan 26, 2017 · 17 comments

Comments

@natiki
Copy link

natiki commented Jan 26, 2017

Hi,

Would you consider adding Copy and Move primitives for both File and Directory? I realise these are not core FTP commands but would make great additions.

The overarching simplification being that as these are compound actions and would require a number of commands to be executed against the FTP server, if something failed half way through then the command returns FALSE and gives up.

@robinrodricks
Copy link
Owner

Sounds like a good idea. Can you specify more details how they would work? What would the method signatures look like?

  • CopyFile(string src, string dest, bool overwrite = true)
  • CopyDirectory(string src, string dest, bool overwrite = true)
  • MoveFile(string src, string dest, bool overwrite = true)
  • MoveDirectory(string src, string dest, bool overwrite = true)

I think move file is similar to rename?

@robinrodricks robinrodricks changed the title Would you consider adding a couple of other conveniences.... Add high-level Copy and Move commands Jan 26, 2017
@natiki
Copy link
Author

natiki commented Jan 29, 2017

Hi,

The signatures look reasonable. I guess the only thing that may be added somewhere is the FtpListOption as that would affect how files/folders are discovered.

In terms of how they would work.... In my head they would be an all or nothing operation without any form of transactional support. So if you were moving a directory tree and ran into issues along the way the method would return false and throw some form of exception.

Move file is not totally similair to rename as move might change location and name of the file.

@robinrodricks
Copy link
Owner

Approximately how will these commands work? I need some more info before I can begin implementing this.

  • CopyFile
    • download file to disk/stream (direct server to server is not possible with FTP, only SFTP can do that)
    • upload file to server
  • CopyDirectory
    • download entire folder recursively to disk (not into memory since it can be too big???)
    • upload directory to server, file by file
  • MoveFile
    • same as Rename? can Rename be used to move a file from X to Y?
    • if you can do some tests with Rename to check its behavior it would speed up the implementation of this feature
  • MoveDirectory
    • same as Rename? can Rename be used to move an entire folder?
    • if you can do some tests with Rename to check its behavior it would speed up the implementation of this feature

@robinrodricks
Copy link
Owner

@natiki - Can you check if the above pseudo code looks ok so I can begin implementing it?

@natiki
Copy link
Author

natiki commented Feb 21, 2017

@hgupta9 Have not forgotten about this. Will let you know in a couple of days.

@robinrodricks
Copy link
Owner

Can you respond please?

@natiki
Copy link
Author

natiki commented Mar 7, 2017

Apologies for the delay....

You should have a look at the FTP commands RNFR and RNTO as these will allow you to do the above operations on the server without the need to download the files and upload them again. Below is an example of me moving a folder /Blah to /Blah3

[08:39:51] [R] MKD /Blah3
[08:39:51] [R] 257-"/Blah3" : The directory was successfully created
[08:39:51] [R] 257 224130 Kbytes used (10%) - authorized: 2097152 Kb
[08:40:13] [R] CWD /Blah
[08:40:13] [R] 250 OK. Current directory is /Blah
[08:40:13] [R] PWD
[08:40:13] [R] 257 "/Blah" is your current location
[08:40:13] [R] CWD /Blah3
[08:40:13] [R] 250 OK. Current directory is /Blah3
[08:40:13] [R] PWD
[08:40:13] [R] 257 "/Blah3" is your current location
[08:40:13] [R] CWD /
[08:40:13] [R] 250 OK. Current directory is /
[08:40:13] [R] PWD
[08:40:13] [R] 257 "/" is your current location
[08:40:13] [R] PASV
[08:40:13] [R] 227 Entering Passive Mode (118,127,42,204,117,178)
[08:40:13] [R] Opening data connection IP: 118.127.42.204 PORT: 30130
[08:40:13] [R] MLSD
[08:40:13] [R] 150 Accepted data connection
[08:40:13] [R] 226-Options: -a -l 
[08:40:13] [R] 226 6 matches total
[08:40:13] [R] List Complete: 659 bytes in 0.04 seconds (0.6 KB/s)
[08:40:13] [R] RNFR /Blah/sample.pas.txt
[08:40:13] [R] 350 RNFR accepted - file exists, ready for destination
[08:40:13] [R] RNTO /Blah3/sample.pas.txt
[08:40:13] [R] 250 File successfully renamed or moved
[08:40:13] [R] RNFR /Blah/template.info
[08:40:13] [R] 350 RNFR accepted - file exists, ready for destination
[08:40:13] [R] RNTO /Blah3/template.info
[08:40:13] [R] 250 File successfully renamed or moved
[08:40:13] [R] PASV
[08:40:13] [R] 227 Entering Passive Mode (118,127,42,204,133,106)
[08:40:13] [R] Opening data connection IP: 118.127.42.204 PORT: 34154
[08:40:13] [R] MLSD
[08:40:13] [R] 150 Accepted data connection
[08:40:13] [R] 226-Options: -a -l 
[08:40:13] [R] 226 6 matches total
[08:40:13] [R] List Complete: 659 bytes in 0.04 seconds (0.6 KB/s)
[08:40:13] Transfer queue completed
[08:40:13] Transferred 0 Files (0 bytes) in 0.21 seconds (0.0 KB/s)

I would guess you could do all operations this way even copy as long as you generated a new name to avoid name conflicts.

@robinrodricks
Copy link
Owner

That's amazing! I will look into supporting these FTP commands.

@robinrodricks
Copy link
Owner

robinrodricks commented Mar 14, 2017

I just checked the code and Rename does exactly that. It first executes RNFR and if it succeeds it executes RNTO. It can be used as a backend for MoveFile and MoveDirectory. However for copying we will first have to download and re-upload.

@natiki
Copy link
Author

natiki commented Mar 14, 2017

Well for copy you could do the same as the above if you generate a temporary top level name and then change it to what it needs to be etc. as long as there is no conflict.

@robinrodricks
Copy link
Owner

robinrodricks commented Mar 14, 2017

But how would we preserve the source file/dir if we have moved it to a new path?

@natiki
Copy link
Author

natiki commented Mar 14, 2017

Have a look at FXP https://en.wikipedia.org/wiki/File_eXchange_Protocol. If the server supports it then you don't have to download first.

@robinrodricks
Copy link
Owner

Its complicated but sounds decent enough once implemented. To add to the fact that most servers have it disabled .. "As a result of this, FTP server software often has FXP disabled by default."

I think downloading and uploading seems like a simple enough solution until this FXP system can be implemented.

@robinrodricks
Copy link
Owner

Implemented MoveFile() and MoveDirectory() in trunk. Advantages over Rename() include :

  • In Skip mode, if the dest already exists the operation is skipped
  • In Overwrite mode, if the dest already exists it is deleted first, and then the Rename() is performed

@sergeushenecz
Copy link

Will you implement FXP?

@robinrodricks
Copy link
Owner

@sergeu90 To add to the fact that most servers have FXP disabled .. "As a result of this, FTP server software often has FXP disabled by default."

@Koxbox360
Copy link

Moving files between the directories in server was exactly what i needed. I couldn't find it in the examples, searched it on google and got me here. Thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants