I must say that this is a working version:

public async static void SendFileToFtp(string ftpAddress, string ftpUser, string ftpPassword, FileInfo file) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(String.Format("{0}{1}", ftpAddress,file.Name)); request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.KeepAlive = false; request.UseBinary = true; request.Method = WebRequestMethods.Ftp.UploadFile; FileStream fs = File.OpenRead(file.FullName); byte[] sBuffer = new byte[fs.Length]; await fs.ReadAsync(sBuffer, 0, sBuffer.Length); fs.Close(); Stream stream = await request.GetRequestStreamAsync(); await stream.WriteAsync(sBuffer, 0, sBuffer.Length); stream.Close(); } 

The crux of the matter is whether or not await is too much in this case. Of course, await request should be, but does it make sense to read and write a file with await? (await fs.ReadAsync, await stream.WriteAsync).

As it turned out, this is not redundant, but normal, and only that you can wrap the threads in using. Also, the working version will be such but the problem with the security of running FtpWebRequest will remain.

 public async static void SendFileToFtp(string ftpAddress, string ftpUser, string ftpPassword, FileInfo file) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(String.Format("{0}{1}", ftpAddress, file.Name)); request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.KeepAlive = false; request.UseBinary = true; request.Method = WebRequestMethods.Ftp.UploadFile; using (FileStream fs = new FileStream(file.FullName, FileMode.Open)) { byte[] sBuffer = new byte[fs.Length]; await fs.ReadAsync(sBuffer, 0, sBuffer.Length); fs.Close(); using (Stream stream = await request.GetRequestStreamAsync()) { await stream.WriteAsync(sBuffer, 0, sBuffer.Length); stream.Close(); } } } 

This is solved in an easy way, here is the link with MSDN https://msdn.microsoft.com/ru-ru/library/system.net.ftpwebrequest(v=vs.110).aspx

  • all three operations are potentially long, so personally I don’t see redundancy. But I would use using in work with streams, since any of the operations with threads and the request itself can throw an exception and things will not come to close , and the threads are very desirable to dispose of, regardless of the result of the operation as a whole. - rdorn
  • Ok, we wrap the threads. FtpWebRequest itself cannot be wrapped, it does not have an IDisposable. Such code for streams turned out: using (FileStream fs = new FileStream (file.FullName, FileMode.Open)) {byte [] sBuffer = new byte [fs.Length]; await fs.ReadAsync (sBuffer, 0, sBuffer.Length); fs.Close (); using (Stream stream = await request.GetRequestStreamAsync ()) {await stream.WriteAsync (sBuffer, 0, sBuffer.Length); stream.Close (); }} - Pannacottik
  • In your last example, the extra 'fs.Close ();' - Vasek
  • Thank you clean. And stream.Close () is not superfluous, by analogy or in this case, we just release the remote resource? - Pannacottik
  • @Pannacottik will surely be. For the Close and Dispose threads, it’s the same thing - Pavel Mayorov

1 answer 1

No, there is no redundancy. You should only wrap the threads in the using construct.

So let it be so. Security FtpWebRequest leave behind the scenes.

 public async static void SendFileToFtp(string ftpAddress, string ftpUser, string ftpPassword, FileInfo file) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(String.Format("{0}{1}", ftpAddress, file.Name)); request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.KeepAlive = false; request.UseBinary = true; request.Method = WebRequestMethods.Ftp.UploadFile; using (FileStream fs = new FileStream(file.FullName, FileMode.Open)) { byte[] sBuffer = new byte[fs.Length]; await fs.ReadAsync(sBuffer, 0, sBuffer.Length); using (Stream stream = await request.GetRequestStreamAsync()) { await stream.WriteAsync(sBuffer, 0, sBuffer.Length); } } } 

You can ask for such solutions to write to another stream (directly to the server) without prior buffering.

 public async static void SendFileToFtp(string ftpAddress, string ftpUser, string ftpPassword, FileInfo file) { FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(String.Format("{0}{1}", ftpAddress, file.Name)); request.Credentials = new NetworkCredential(ftpUser, ftpPassword); request.KeepAlive = false; request.UseBinary = true; request.Method = WebRequestMethods.Ftp.UploadFile; using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, true)) { using (Stream stream = await request.GetRequestStreamAsync()) { await fs.CopyToAsync(stream); } } } 
  • Isn't it better to use fs.CopyToAsync(stream) ? The file can be big ... - Pavel Mayorov
  • I actually do not know what this will be. What does CopyToAsync do? Type immediately without copying to the buffer? - Pannacottik
  • Reads everything from one thread and writes to another. - Pavel Mayorov
  • And yes, the file can be large and plus the same operations can be run in another session. - Pannacottik
  • Thank you, recorded in the decision in addition. It should be noted turned out succinctly. - Pannacottik