❔ recommended FTP library/nuget?
Well, I need to to a task via FTP:
- if exist delete a folder with its content
- upload a folder with its files
I'm trying to to that using
FtpWebRequest Class
but it seems that's a bit limited, I'm still reading MSDocs and it seems that I can't delete a folder recursively, so I get the error "folder is not empty" when trying to delete75 Replies
the RemoveDirectory method seems to not have much in
so I thought to try the most used FTP nuget, what do you think about?
GitHub
GitHub - robinrodricks/FluentFTP: An FTP and FTPS client for .NET &...
An FTP and FTPS client for .NET & .NET Standard, optimized for speed. Provides extensive FTP commands, File uploads/downloads, SSL/TLS connections, Automatic directory listing parsing, File...
Yes i also using this fluent ftp
ok so I'll go for it 😎
is there some documentation?
I'm reading the github one, but i was unable to find an order that explain the basics.
reading this: https://github.com/robinrodricks/FluentFTP/wiki/Class-FtpClient-DeleteDirectory
I was able to write this, I think I did it well, but shouldn't be a part that explain the beginning, I mean the connection with credentials and parameters definition?
GitHub
Class FtpClient DeleteDirectory
An FTP and FTPS client for .NET & .NET Standard, optimized for speed. Provides extensive FTP commands, File uploads/downloads, SSL/TLS connections, Automatic directory listing parsing, File...
I found a sort of index, it seems good, so I'm editing the code like this 🤞
it's awesome I could also put a custom command to execute 😎
I think you can use this.
var client = new AsyncFtpClient("123.123.123.123", "david", "pass123");
await client.AutoConnect();
await client.DeleteDirectory("/htdocs/extras/")
well I setted it all, the only thing on which I'm stuck is credentials definition, should I use tuple?
oh, nice form, I can include parameters directly into it.
I seen this autoconnect but I skipped it since idk how does it act, now I try
do you recommend Async?
isn't missing recursive parameter on deletedirectory?
The autoconect something like connect to ftp. In their previous version it was connect only, after i update to latest it now autoconnect.
Yes i recommend it but if your ftp will be use with many users.
If not you may use the synchronous.
About recursive you may add it as 2nd parameters in delete directory
oh, just found the usage
yeah I have to familiarise with async in general btw since I never used it
regarding the connection, I wrote the code in this way
if I use autoconnect does it know when to disconnect?
You need to disconnect the ftp, after your needs
yeah I wrote a disconnet(); at the end, just tested my code and it works perfect and very very fast, awesome^^ much better than MS thing
in my case I used .Connect() and .Disconnect() so I'm doing all my self, which is so the purpose of AutoConnect() ?
very important question, do you think that deleting a folder with DeleteDirectory() and reuploading the same folder could cause timing problems?
example:
hypnotising the DeleteDirectory need 2 minutes for delete all, will the UploadDirectory start after 2 mins or it just launch bot commands like when you do ProcessStart without putting .WaitForExit() ?
really I can upload with this Mirror that automatically delete additional files o_O this library is awesome^^
I think I'll still delete and normal upload since I retain that it take less time
you can use the property initialization with that syntax
oh, really prettier than mine, also if I don't understand yet when and how to do this
also, just to be clear: https://github.com/robinrodricks/FluentFTP/wiki/Quick-Start-Example
this was 1 click away at all times :p
actually it works good, just one not serious problem, I can get when trying delete a folder using https://github.com/robinrodricks/FluentFTP/wiki/Class-FtpClient-DeleteDirectory
if the folder does not exist I get this
FluentFTP.Exceptions.FtpCommandException: 'Code: 550 Message: Directory not found'
now I searched into documentation but It seems there's no option to handle this, so it is correct if I use try-catch statement for handle this exception?GitHub
Class FtpClient DeleteDirectory
An FTP and FTPS client for .NET & .NET Standard, optimized for speed. Provides extensive FTP commands, File uploads/downloads, SSL/TLS connections, Automatic directory listing parsing, File...
or jsut check if the directory exists before trying to delete it?
good idea^^ I thought it was implemented in the delete method by the author
no, that would break SRP
SRP?
single responsibility principle
a delete command should just delete, and if it cant, its reasonable to throw an exception
if it always checked for existance before deleting, it would be doing two things - and that would be less flexible
there are times you know the file/directory exists and dont care about checking
after all, its trivial to add them together, you could probably even make an extension method to do so, should you wish
oh, it make sense, so the author should remember to include a directory exist method
yeah I implemented but I have a generic doubt
do you think is more correct
else
or an else if
?
is what I would do.
you could have this return a bool indicating if the folder was deleted or not, if you really need that printout
wow, you pass FtpClient also as parameter
its an extension method
you would call it as normal
ftpClient.DeleteDirectoryIfExists("myfolder", FtpListOption.Recursive);
ok
btw use SFTP not FTP as it is insecure
yeah the final target will be SFTP but I was unable to set it on my xampp so I started with FTP
don't tell me that I can't use it with FluentFTP
You can't. FTPS, sure, but SFTP is a different beast.
hm so in SFTP case I can't use this nuget, right?
correct
:/
it was so awesome^^
lets try this SSH.NET, it seems quite similar
is there an easy way to create/simulate a local SFTP and SSH?
I created the normal one with XAMPP tools that include FileZilla Server
do you have docker installed?
could just spin up a fairly bog-standard linux image
I would disagree that this breaks SRP. Think about all the Try methods, whether it is TryParse(), TryAdd() or any other. They check if its possible but they also perform the actual operation. Does that break SRP? I don't think it does
Well this isn't
TryDeleteDirectory
Try methods are expected to "try"thats right, I'm just saying every method can contain validation and that shouldn't be seen as a responsibility unless the validation really is the responsibility if that makes sense. If you're writing a method for validation then of course it's only responsibility should be validation and nothing else but if the responsibility is something else other than validation than having some validation in it doesn't add a second responsiblity to it, does it?
I suppose you could argue its not SRP but more... composability?
since each operation performed in FTP has a roundtrip associated with it, its certainly not free to check if a directory exists or not
so if you need that behaviour, its fairly easy to compose it yourself, as I showed above
but its good that it doesnt by default
yeah I agree
just wanted to make sure that if we write a method ourselves called ´WriteToFile´ then checking first if there already is such file doesn't break SRP. But agreeing with everything else you've said
Not sure I entirely agree for that case. If its part of a larger responsiblity, thats fine.
"This method is responsible for saving my application data to a file."
but if its a generic
WriteToFile
, then suddenly that changes things
Like, where do you draw the line for what should throw exceptions and what should the method handle for you?
File.WriteAllText
for example will create the file if it doesnt exist, otherwise open and overwrite. it will however throw exceptions if the path isnt writable, or if it failed to secure a file handle
Makes sense, since this is supposed to be the "easy to use" method. it should do what is feasible
but if it can't, then it seems appropriate to throw exceptions
so yeah, it might be fine to validate, it all depends on the purpose and how generic or not it is. imo.thats a good summary 🙂
no I did it with virtualbox, but I'll try one day, I heard this docker use very low resources
I'm making initial tests with SSH.NET and for try I just setted up a command that create a blank file for see if it successfully connect and act on the server.
So I wrote this code, the .txt file is created, but the console for some reason is stuck on "Using SSH . . ."
edit: just tried to manually do it via PuTTy, and the result is the same, after I write "cat > file.txt" I'm no able to go on or type further commands till I press CTRL+C, what could be?
ok it seems it's a particular of "cat" command, I just tried to deleting a dir and it works
cat
prints from a stream to the console
you gave it no arguments, so its reading from STDIN
if you just wanted to make a file, you use echo hello > bydotnet.txt
or simpler, touch bydotnet.txt
oh, ok
now I'm replicating the old function FluentFTP into SSH.NET
it seems deleting folder and content don't need any check, it works in any case this code:
the only complicated thing seems the folder upload, old code is
about the new code currently I still don't know how to proceed, I downloaded the documentation of this SSH.NET but is in .chm extension, and it seems text is not loading, so I'm trying to convert it in PDF
public class SftpClient : BaseClient, ISftpClient
this seems promising
It can do more than that tho. The way he uses it with
cat > filename.txt
it should open a stream from the console to the file. After that you can insert text in the console that gets written directly into the file. So missing arguments can’t be the reason why it’s not working, whatever else may be the reason...
if you open up a shell right now and type
cat > filename.txt
you can answer that question yourselfrsa?
it prints from a stream to an output, usually STDOUT. In this case, that output is redirected to a file
you can log in however you want, of course
you dont have to use pkey auth
what does it do? I know what rsa is, but idk what does it do, is a security setting?
yes
its a different way of authenticating, aka proving an identity
so it generate automatically this rsa.key
no
its logging in using private key authentication
I'm guessing the
ConnectionInfo
ctor takes in a params IAuthenticationMethod[]
and it tries them in orderwhat question can I answer myself? I didn't ask a question
So missing arguments can’t be the reason why it’s not working, whatever else may be the reasonthat command,
cat > filename.txt
, redirects stdin
on a normal term, you'd press CTRL+D or whatever you have bound to that
to stop the stream, which lets cat write the file, flush, and terminateahhh now I understand, ty
am I doing something wrong?
yes
your client is of type
SshClient
you need an SftpClient
oh, my bad :/
SshClient
and SftpClient
are interfaces, right?nope.
ISftpClient
is an interface
SftpClient
is a class implementing said interfaceok
well, there is no trace of "folder"/"directory", and if I Ctrl+F on the guide with "recurs" I get 0 results, guessing I can't upload folders with their content
should I switch to WinSCP?
winSCP is an excellent client, its what I use myself
but i have never tried automating it
as I read online its nuget pack allow SSH connections and Folder uploads
or maybe not, someone here wrote a function that theoretically should do the job
https://stackoverflow.com/questions/39397746/ssh-net-upload-whole-folder
I'm reading for understand better what does this cycle do
Stack Overflow
SSH.NET Upload whole folder
I use SSH.NET in C# 2015.
With this method I can upload a file to my SFTP server.
public void upload()
{
const int port = 22;
const string host = "**";
const string username = "...
idk in this sample there's a function that call itself 🧐
yes?
you know what thats called?
its called a recursive function
and you are trying to do a recursive folder upload, no?
yes
it works very well but I'll try to understand the process, also I have to understand where put the .Connect();
for test I just putted it randomly into the function using a rough trycatch for avoiding the error "already connected", but if I'm not wrong, the correct form should be
oh, maybe I can pass
sftpClient
instead of instantiating a new one
ok it works very very well, last little problem is that he expect all the folders and subfolder already exist in the destination, or it throw up this Renci.SshNet.Common.SftpPathNotFoundException: 'No such file'
if I could mix sshClient
and sftpClient
I could just create the folder when it does not exist through sshClient commands 🦊
but I think it's not possible so I'll try to edit this sshClient.RunCommand("rm -rf myfolder");
in order to make it only empty the folder from files hoping it will leave subfolders
or maybe none of them, I get error on sftpClient.CreateDirectory(subPath);
so it provide a folder creation method, I think the main problem is that the root folder is previously deleted by me, if so I can solve easilyWas this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.