Downloading from FTP with c#, can't retry when

2019-09-05 00:03发布

问题:

I have an application for download Zip files from an FTP.

Many times I got connection problems while a file is downloading so I have to retry but I can't do it.

When I try to download de file again with this line "reader = response.GetResponseStream();" I got the follow messagge "The process cannot access the file xxx because it is being used by another process". I decided to close the writer stream (memStream) in the catch and sometimes it works but sometimes when I try to get de respose again it doesn't work a give me a time out exception.

Is there an clear way to retry download a file from FTP without errors?

EDIT: I see that I can start download again the first file that fail but when another file fail I can't get the response from the request and gimme the time out

Here is the code:

FtpWebResponse response = null;
FtpWebRequest request = null;
Stream memStream = null;
Stream reader = null;
Directory.CreateDirectory(pathDestino);

                try
                {
                    request = FtpWebRequest.Create(urlArchivo) as FtpWebRequest;
                    request.Credentials = new NetworkCredential("ftp", "ftp");


                //Now get the actual data
                request = FtpWebRequest.Create(urlArchivo) as FtpWebRequest;
                request.Method = WebRequestMethods.Ftp.DownloadFile;
                request.Credentials = new NetworkCredential("ftp", "ftp");
                request.UsePassive = true;
                request.UseBinary = true;
                request.KeepAlive = false; //close the connection when done
                if(totalBytes!=0)  //check if a file failed
                {
                    request.ContentOffset=totalBytes;
                }
                //Streams
                response = request.GetResponse() as FtpWebResponse;
                reader = response.GetResponseStream();
                //Download to memory
                //Note: adjust the streams here to download directly to the hard drive
                //MemoryStream memStream = new MemoryStream();
                string pathCompleto = pathDestino + @"\" + horaMinuto + ".zip";
                memStream = File.Create(pathCompleto);
                byte[] buffer = new byte[1024]; //downloads in chuncks
                int bytesAcum = 0;
                while (true)
                {

                    int bytesRead = reader.Read(buffer, 0, buffer.Length);

                    if (bytesRead == 0)
                    {                        
                        break;
                    }
                    else
                    {
                        //Write the downloaded data
                        memStream.Write(buffer, 0, bytesRead);
                        totalBytes=+bytesRead;
                    }
                }

                //Convert the downloaded stream to a byte array
                //downloadedData = memStream.ToArray();

                //Clean up
                reader.Close();
                memStream.Close();
                response.Close();
                totalBytes=0;

            }

catch
{
//something
memStream.Close();
request.Abort();
}

回答1:

Typically "resume" in FTP involves requesting the file again from a specific file byte offset.

Looking at FtpWebRequest class, the property you need to populate once the connection fails will be the length of your already downloaded buffer and you should set the property ContentOffset.

More information on this property at the link: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.contentoffset(v=vs.110).aspx