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();
}
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 propertyContentOffset
.More information on this property at the link: http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.contentoffset(v=vs.110).aspx