0

I have tried to download an FTP file using C# and have had various problems. What I want to achieve is to be able to show download progress in a progressBar. It is important that I use Windows Form and .Net.

I have tried two codes;

My first code works perfectly, that is, I can download the FTP file without problems.

CODE 1

FtpWebRequest dirFtp = ((FtpWebRequest)FtpWebRequest.Create(ficFTP));
        dirFtp.KeepAlive = true;
        dirFtp.UsePassive = UsePassive;
        dirFtp.UseBinary = UseBinary;            

        // Los datos del usuario (credenciales)
        NetworkCredential cr = new NetworkCredential(user, pass);
        dirFtp.Credentials = cr;                  
        FtpWebResponse response = (FtpWebResponse)dirFtp.GetResponse();
        long size = (long)response.ContentLength;
        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);


        using (FileStream writer = new FileStream(dirLocal, FileMode.Create))
        {

            int bufferSize = 2048;
            int readCount;
            byte[] buffer = new byte[2048];

            readCount = responseStream.Read(buffer, 0, bufferSize);
            while (readCount > 0)
            {

                writer.Write(buffer, 0, readCount);
                readCount = responseStream.Read(buffer, 0, bufferSize);                   

            }

        }
        lblDescarga.Text = "¡Downloaded!";
        reader.Close();
        response.Close();            

Problem with this code

My problem with this code is that I can't get the size of the FTP file to be able to use the progressBar, In theory this section of code would tell me the size of my file but it always returns -1:

long size = (long)response.ContentLength;

As this did not work as I wanted, I made a post and people recommended this solution FtpWebRequest FTP download with ProgressBar:

CODE 2

 try
        {
            const string url = "ftp://185.222.111.11:21/patch/archive.zip";
            NetworkCredential credentials = new NetworkCredential("user", "pass");

            // Query size of the file to be downloaded
            WebRequest sizeRequest = WebRequest.Create(url);
            sizeRequest.Credentials = credentials;
            sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;                
            int size = (int)sizeRequest.GetResponse().ContentLength;

            progressBar1.Invoke(
                (MethodInvoker)(() => progressBar1.Maximum = size));

            // Download the file
            WebRequest request = WebRequest.Create(url);
            request.Credentials = credentials;
            request.Method = WebRequestMethods.Ftp.DownloadFile;

            using (Stream ftpStream = request.GetResponse().GetResponseStream())
            using (Stream fileStream = File.Create(@"C:\tmp\archive.zip"))
            {
                byte[] buffer = new byte[10240];
                int read;
                while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fileStream.Write(buffer, 0, read);
                    int position = (int)fileStream.Position;
                    progressBar1.Invoke(
                        (MethodInvoker)(() => progressBar1.Value = position));
                }
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }

Problem with this code

The problem with this code is when it gets to this point:

int size = (int) sizeRequest.GetResponse (). ContentLength;

Remote server error: (550) File not available (eg file not found or not accessed).

The truth is that it is impossible to tell that you do not have permission if code 1 works well. However I have the normal permissions in FTP, could someone give me an idea please?

mujuonly
  • 11,370
  • 5
  • 45
  • 75
jose angarita
  • 199
  • 1
  • 12
  • 1
    Don't use `Passive` mode, if possible, or load the detailed file list (i.e., make an initial FtpWebRequest with `WebRequestMethods.Ftp.ListDirectoryDetails`), read the file length so your buffer length now lets you calculate the progress. --- Use a different library. --- You can also try WebClient (with `DownloadFileAsync` or `DownloadFileTaskAsync`), if possible. +++ Why have you tagged this question both asp.net and WinForms? These platforms are quite unrelated. – Jimi Apr 14 '20 at 08:39
  • I am learning the world of C # According to the visual study, my project is Windows Form from .net – jose angarita Apr 14 '20 at 09:24
  • Well, then `asp.net` and `asp.net-core` are completely unrelated. Anyway, what I commented about before stands. – Jimi Apr 14 '20 at 09:26
  • Excuse me, could you explain a little example of what you have told me? I mean about knowing the size of the FTP file – jose angarita Apr 14 '20 at 09:28
  • If you use Passive mode, you cannot know the length of the Stream. So, or you don't use Passive mode, or you download the file list first and read the file length there or you use a library that has a more direct approach than the (really lacking and generic) FtpWebRequest implementation. – Jimi Apr 14 '20 at 09:31
  • I have implemented passive mode as false and it keeps showing me -1 – jose angarita Apr 14 '20 at 09:35
  • I would recommend you to try very popular and free WinSCP which support file transfer progress: https://winscp.net/eng/docs/library_session_filetransferprogress#csharp – Tomas Paul Apr 15 '20 at 16:11
  • ohhh Thank u Tomas. – jose angarita Apr 16 '20 at 12:45

0 Answers0