FtpWebRequest FTP download with ProgressBar - c#

My code works, but the ProgressBar jumps directly to 100% and the download will go on. When its finished then comes a messageBox to take a Info.
I have already changed the buffer size, but it doesn't matter.
What am I doing wrong here?
Here is my Code:
void workerDOWN_DoWork(object sender, DoWorkEventArgs e)
{
string fileFullPath = e.Argument as String;
string fileName = Path.GetFileName(fileFullPath);
string fileExtension = Path.GetExtension(fileName);
label4.Invoke((MethodInvoker)delegate { label4.Text = "Downloading File.."; });
string ftpServerIP = "XXX";
string ftpUserName = "XXX";
string ftpPassword = "XXX";
try
{
//Datei vom FTP Server downloaden
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(fileFullPath))
{
var buffer = new byte[32 * 1024];
int totalReadBytesCount = 0;
int readBytesCount;
while ((readBytesCount = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, readBytesCount);
totalReadBytesCount += readBytesCount;
var progress = (int)((float)totalReadBytesCount / (float)fileStream.Length * 100);
workerDOWN.ReportProgress((int)progress);
label3.Invoke((MethodInvoker)delegate { label3.Text = progress + " %"; });
}
}
}
catch (WebException ex)
{
FtpWebResponse response = (FtpWebResponse)ex.Response;
if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
MessageBox.Show("Datei nicht gefunden!", "Error");
}
}
e.Result = fileFullPath;
}
void workerDOWN_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string fileFullPath = e.Result as String;
string fileName = Path.GetFileName(fileFullPath);
MessageBox.Show("Download erfolgreich!","Information");
progressBar1.Value = 0;
label3.Invoke((MethodInvoker)delegate { label3.Text = " "; });
label4.Invoke((MethodInvoker)delegate { label4.Text = " "; });
}

Trivial example of FTP download using FtpWebRequest with WinForms progress bar:
private void button1_Click(object sender, EventArgs e)
{
// Run Download on background thread
Task.Run(() => Download());
}
private void Download()
{
try
{
const string url = "ftp://ftp.example.com/remote/path/file.zip";
var credentials = new NetworkCredential("username", "password");
// 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:\local\path\file.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);
}
}
The core download code is based on:
Upload and download a file to/from FTP server in C#/.NET
To explain why your code does not work:
You are using size of the target file for the calculation: fileStream.Length – It will always be equal to totalReadBytesCount, hence the progress will always be 100.
You probably meant to use ftpStream.Length, but that cannot be read.
Basically with FTP protocol, you do not know size of the file you are downloading. If you need to know it, you have to query it explicitly before the download. Here I use the WebRequestMethods.Ftp.GetFileSize for that.

i have now a solution thats work for me.
The Idea to get first the File Size was great.
But when i first makes an query to check the File Size, the Ftp Server throws a Error. Like this
FtpWebRequest error: 550 Size not allowed in ASCII mode
Now first i download a dummy file to open the Connection.. See below
Thanks to all for the Support.
Great Community. Thanks.
void workerDOWN_DoWork(object sender, DoWorkEventArgs e)
{
string fileFullPath = e.Argument as String;
string fileName = Path.GetFileName(fileFullPath);
string fileExtension = Path.GetExtension(fileName);
label4.Invoke((MethodInvoker)delegate { label4.Text = "Downloading File.."; });
//FTP Download und Delete
string ftpServerIP = "XXX";
string ftpUserName = "XXXX";
string ftpPassword = "XXXXX";
try
{
// dummy download ftp connection for ftp server bug
FtpWebRequest DummyRequest = (FtpWebRequest)WebRequest.Create(("ftp://" + ftpServerIP + "/anyfile"));
DummyRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
DummyRequest.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = DummyRequest.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(Path.GetDirectoryName(Application.ExecutablePath) + "\\anyfile"))
{
ftpStream.CopyTo(fileStream);
}
//delete downloaded test file
File.Delete(Path.GetDirectoryName(Application.ExecutablePath) + "\\anyfile");
// Query size of the file to be downloaded
FtpWebRequest sizeRequest = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
sizeRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
sizeRequest.Method = WebRequestMethods.Ftp.GetFileSize;
var fileSize = sizeRequest.GetResponse().ContentLength;
//file download
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
request.Method = WebRequestMethods.Ftp.DownloadFile;
using (Stream ftpStream = request.GetResponse().GetResponseStream())
using (Stream fileStream = File.Create(fileFullPath))
{
var buffer = new byte[32 * 1024];
int totalReadBytesCount = 0;
int readBytesCount;
while ((readBytesCount = ftpStream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, readBytesCount);
totalReadBytesCount += readBytesCount;
var progress = (int)((float)totalReadBytesCount / (float)fileSize * 100);
workerDOWN.ReportProgress((int)progress);
label3.Invoke((MethodInvoker)delegate { label3.Text = progress + " %"; });
}
}
// delete file on ftp server
FtpWebRequest Delrequest = (FtpWebRequest)WebRequest.Create("ftp://" + ftpServerIP + "/" + fileName);
Delrequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
Delrequest.Method = WebRequestMethods.Ftp.DeleteFile;
FtpWebResponse Delresponse = (FtpWebResponse)Delrequest.GetResponse();
Delresponse.Close();
// message file deleted
richTextBox1.Invoke((MethodInvoker)delegate { richTextBox1.AppendText("System: " + fileName + " wurde auf dem Server gelöscht." + Environment.NewLine); });
}
catch (WebException ex)
{
FtpWebResponse response = (FtpWebResponse)ex.Response;
if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
MessageBox.Show("Datei nicht gefunden!", "Error");
}
}
e.Result = fileFullPath;
}
void workerDOWN_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
void workerDOWN_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string fileFullPath = e.Result as String;
string fileName = Path.GetFileName(fileFullPath);
MessageBox.Show("Download erfolgreich!","Information");
progressBar1.Value = 0;
label3.Invoke((MethodInvoker)delegate { label3.Text = " "; });
label4.Invoke((MethodInvoker)delegate { label4.Text = " "; });
}

Without knowing exactly what your code in the ProgressChanged eventhandler does, I think that you unintentionally put the brackets in your progress calculation after * 100.
You could try this:
var progress = (int)((float)totalReadBytesCount / (float)fileStream.Length) * 100;

Related

async/await ftpupload damages uploaded file

I am trying to ftpupload a zipfile with async/await pattern:
private async void button2_Click(object sender, RoutedEventArgs e)
{
await processFtp();
}
async Task processFtp()
{
string result = "";
string ftpHost = "ftp://mysite/mysubdir";
string ftpUser = "itsme";
string ftpPassword = "mypw";
string ftpfullpath = ftpHost + "/" + "OutdoorTest.zip";
string fileToUpload = #"c:\temp\Outdoorbilder.zip";
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpfullpath);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(ftpUser,ftpPassword);
request.UseBinary = true;
request.KeepAlive = false;
request.ReadWriteTimeout = 1000000;
request.Timeout = 1000000;
using (Stream requestStream = request.GetRequestStream())
{
using (FileStream fs = File.OpenRead(fileToUpload))
{
byte[] b = new byte[10 * 1024];
int readLength = 0;
int sentLength = 0;
while ((readLength = fs.Read(b, 0, b.Length)) > 0)
{
await requestStream.WriteAsync(b, 0, b.Length);
int percentComplete = (int)((float)(sentLength += readLength) / (float)fs.Length * 100);
ftpprogress.Value = percentComplete;
}
requestStream.Close();
requestStream.Flush();
}
}
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
response.Close();
result = response.StatusDescription;
}
catch (WebException e)
{
result = e.Message;
if (e.Status == WebExceptionStatus.ProtocolError)
{
result = result + "Status Code : " +
((FtpWebResponse)e.Response).StatusCode;
result = result + "\nStatus Description : " +
((FtpWebResponse)e.Response).StatusDescription;
}
}
catch (Exception e)
{
result = e.Message;
}
MessageBox.Show(result);
}
}
The code seems to work fine and I get a 226 response. But the zip file on the ftp server is arround 1000bytes biger than the original and after download to a mobile android device cannot be opend/extracted.
When I upload without async/await pattern the uploaded file has the same size on ftp server as the local original.
How/where does this happen?
This has nothing to do with async/await.
Your problem is that you are not telling the correct size to upload. Look at these two lines:
while ((readLength = fs.Read(b, 0, b.Length)) > 0)
{
await requestStream.WriteAsync(b, 0, b.Length);
You need to specify that the WriteAsyc writes the read amount and not the amount allocated for the byte buffer. At least the last read will return less than the buffer size.
So the correct code is:
while ((bytesRead = fs.Read(b, 0, b.Length)) > 0)
{
await requestStream.WriteAsync(b, 0, bytesRead);

File size detection before downloading from an ftp server? C# error

I have a C# homework, to create a download manager to download a file from an ftp server, with these conditions:
Selection of an audio file on a server.
Detection of file size.
Asynchronous transmission of the file to your work PC via ftp.
Representation of the progress of the download.
Actually, I have completed three of them, almost all, except some error occured with the second condition when I tried to get the file size before downloading, my program crashed and an error happened like this:
Error
This is the code for my downloader:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
namespace DownloadDataFTP
{
public partial class ftpForm : Form
{
public ftpForm()
{
InitializeComponent();
}
private byte[] downloadedData;
//Connects to the FTP server and downloads the file
private void downloadFile(string FTPAddress, string filename, string username, string password)
{
downloadedData = new byte[0];
try
{
//Create FTP request
//Note: format is ftp://server.com/file.ext
FtpWebRequest request = FtpWebRequest.Create(FTPAddress + "/" + filename) as FtpWebRequest;
//Get the file size first (for progress bar)
request.Method = WebRequestMethods.Ftp.GetFileSize;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true; //don't close the connection
int dataLength = (int)request.GetResponse().ContentLength;
//Now get the actual data
request = FtpWebRequest.Create(FTPAddress + "/" + filename) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false; //close the connection when done
//Set up progress bar
progressBar1.Value = 0;
progressBar1.Maximum = dataLength;
lbProgress.Text = "0/" + dataLength.ToString();
//Streams
FtpWebResponse response = request.GetResponse() as FtpWebResponse;
Stream reader = response.GetResponseStream();
//Download to memory
//Note: adjust the streams here to download directly to the hard drive
MemoryStream memStream = new MemoryStream();
byte[] buffer = new byte[1024]; //downloads in chuncks
while (true)
{
Application.DoEvents(); //prevent application from crashing
//Try to read the data
int bytesRead = reader.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
//Nothing was read, finished downloading
progressBar1.Value = progressBar1.Maximum;
lbProgress.Text = dataLength.ToString() + "/" + dataLength.ToString();
Application.DoEvents();
break;
}
else
{
//Write the downloaded data
memStream.Write(buffer, 0, bytesRead);
//Update the progress bar
if (progressBar1.Value + bytesRead <= progressBar1.Maximum)
{
progressBar1.Value += bytesRead;
lbProgress.Text = progressBar1.Value.ToString() + "/" + dataLength.ToString();
progressBar1.Refresh();
Application.DoEvents();
}
}
}
//Convert the downloaded stream to a byte array
downloadedData = memStream.ToArray();
//Clean up
reader.Close();
memStream.Close();
response.Close();
MessageBox.Show("Downloaded Successfully");
}
catch (Exception)
{
MessageBox.Show("There was an error connecting to the FTP Server.");
}
txtData.Text = downloadedData.Length.ToString();
this.Text = "Download and Upload Data through FTP";
username = string.Empty;
password = string.Empty;
}
//Upload file via FTP
private void Upload(string FTPAddress, string filePath, string username, string password)
{
//Create FTP request
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(FTPAddress + "/" + Path.GetFileName(filePath));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
//Load the file
FileStream stream = File.OpenRead(filePath);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
//Upload file
Stream reqStream = request.GetRequestStream();
reqStream.Write(buffer, 0, buffer.Length);
reqStream.Close();
MessageBox.Show("Uploaded Successfully");
}
//get file size for downloading
private void FileSize_down(string FTPAddress, string filename)
{
FtpWebRequest request = FtpWebRequest.Create(FTPAddress + "/" + filename) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.GetFileSize;
long dataLength = (long)request.GetResponse().ContentLength;
sizeFile.Text = dataLength.ToString();
}
//get file size for uploading
private void FileSize_up(string filename)
{
if (UpFile.Text != "")
{
//direction file
FileInfo f = new FileInfo(UpFile.Text);
//add size to text box
textBox1.Text = f.Length.ToString();
}
else
MessageBox.Show("Choose file to upload");
}
//Connects to the FTP server and request the list of available files
private void getFileList(string FTPAddress, string username, string password)
{
List<string> files = new List<string>();
try
{
//Create FTP request
FtpWebRequest request = FtpWebRequest.Create(FTPAddress) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
FtpWebResponse response = request.GetResponse() as FtpWebResponse;
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
while (!reader.EndOfStream)
{
Application.DoEvents();
files.Add(reader.ReadLine());
}
//Clean-up
reader.Close();
responseStream.Close(); //redundant
response.Close();
}
catch (Exception)
{
MessageBox.Show("There was an error connecting to the FTP Server");
}
username = string.Empty;
password = string.Empty;
this.Text = "Download and Upload Data through FTP"; //Back to normal title
//If the list was successfully received, display it to the user
//through a dialog
if (files.Count != 0)
{
listDialogForm dialog = new listDialogForm(files);
if (dialog.ShowDialog() == DialogResult.OK)
{
//Update the File Name field
txtFileName.Text = dialog.ChosenFile;
}
}
}
//Make sure the FTP server address has ftp:// at the beginning
private void txtFTPAddress_Leave(object sender, EventArgs e)
{
if (!txtFTPAddress.Text.StartsWith("ftp://"))
txtFTPAddress.Text = "ftp://" + txtFTPAddress.Text;
}
This is the part that gets file size for download.
//get file size for downloading
private void FileSize_down(string FTPAddress, string filename)
{
FtpWebRequest request = FtpWebRequest.Create(FTPAddress + "/" + filename) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.GetFileSize;
long dataLength = (long)request.GetResponse().ContentLength;
sizeFile.Text = dataLength.ToString();
}
Thanks so much!
You are getting a 530 (not logged in) error. Seems like that is the issue. In your other methods(downloadFile, getFileList, etc) you include:
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
in your Filesize_down you do not.

Why Ftp Downloading is so slow with c# / FtpWebRequest

I'm using the FTP function in c# in order to download somes files.
My problem is that the download is slow.
I don't have any problem with Filezilla, and my connection is OK.
I'm thinking about the FTP functions implementations, here is my code :
public static string DownloadFromList(string strParam,string filePath)
{
string[] FilesToDownload = strParam.Split('\n');
try
{
FtpWebRequest reqFTP;
foreach(string file in FilesToDownload)
{
string tmpfile = file;
if (tmpfile.Contains("\n"))
{
tmpfile = tmpfile.Replace('\n', ' ');
}
FileInfo fileToDownload = new FileInfo(tmpfile);
tmpfile = fileToDownload.Name;
FileStream outputStream = new FileStream(filePath.Trim() + "\\" + tmpfile.Trim(), FileMode.Create);
if (strDirectory.Trim() != "")
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + strHost.Trim() + "/" + strDirectory.Trim() + "/" + tmpfile.Trim()));
}
else
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + strHost.Trim() + "/" + tmpfile.Trim()));
}
reqFTP.ConnectionGroupName = "MyGroupName";
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.KeepAlive = true;
reqFTP.Timeout = -1;
reqFTP.Credentials = new NetworkCredential(strUser.Trim(), strPass.Trim());
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream ftpStream = response.GetResponseStream();
StreamReader reader = new StreamReader(ftpStream, System.Text.Encoding.UTF8);
long cl = response.ContentLength;
int bufferSize = 8192;
char[] bytesInStream = new char[8192];
int readCount;
StreamWriter sw = new StreamWriter(outputStream);
int len;
while ((len = reader.Read(bytesInStream, 0, bytesInStream.Length)) > 0)
{
sw.Write(bytesInStream, 0, len);
}
sw.Close();
outputStream.Close();
ftpStream.Close();
response.Close();
}
return "ok";
}
catch (Exception ex)
{
return (ex.Message);
}
}
Is it necessary to set useBinary = true ?
KeepAlive is setted to true in order to use the same connection, but is it true ?
Is it possible to set the credential only one time ?
How can i improve this please?
Thanks a lot :)
Best regards,

Remote server error: 150 Opening Binary mode data connection

I am trying to create a small console application that downloads files from a ftp server through Explicit FTP over TLS. I have create these applications before but i am getting an error with this one. I keep Getting this error:
The Remote Server returned an error: 150 Opening BINARY mode data connection fro "filename" <2000 bytes>.
I cant seem to figure out that to do, can anyone help me?
this is my code:
public void DownloadFiles(string fileName)
{
uri.Scheme = "ftp";
uri.Host = ftpUrl;
uri.Port = 21;
uri.UserName = username;
uri.Password = password;
uri.Path = "out";
try
{
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri.ToString() + "/" + fileName));
reqFTP.EnableSsl = true;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response;
response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(localFolder + fileName, FileMode.Create);
long length = response.ContentLength;
int bufferSize = 2048;
Byte[] buffer = new Byte[bufferSize];
int readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writeStream.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
AppendLogFile(response, "Downloading Files: ", fileName);
writeStream.Close();
responseStream.Close();
response.Close();
reqFTP.Abort();
}
catch (Exception ex)
{
Console.WriteLine("Error in DownloadFileByFileName method!! " + ex.Message);
}
}
thanks!
I could not find the solution for this so i when over to use Chillkat for this application. works fine. But needed to buy a year license.
this is my code:
public void Connect(string fileName)
{
bool success;
success = ftp.UnlockComponent("license");
if (!success)
{
Console.WriteLine(ftp.LastErrorText);
return;
}
ftp.IdleTimeoutMs = 10000;
ftp.AuthTls = true;
ftp.Ssl = false;
ftp.Hostname = ftpUrl;
ftp.Port = 21;
ftp.Username = username;
ftp.Password = password;
ftp.KeepSessionLog = true;
success = ftp.Connect();
if (success != true)
{
Console.WriteLine(ftp.LastErrorText);
return;
}
ftp.ClearControlChannel();
bool sucess = ftp.GetFile("out/" + fileName, localFolder + fileName);
if (!success)
{
Console.WriteLine(ftp.LastErrorText);
AppendErrorLogFile("Error in downloading file", "Download file method", fileName);
return;
}
else
{
AppendLogFile("Download Success", "Download File Method", fileName);
ftp.DeleteRemoteFile("out/" + fileName);
}
}
long length = response.ContentLength;
Is at fault here I believe, if you use this to download a file that already exists, your request will close before you can get a response from the server and throw the 150 error.

FtpWebRequest while writing to stream if network goes down then FTP Server gives access denied problem when tried to re upload

I am using FtpWebRequest to upload a file.
Facing a problem of which i am not getting solution.
While uploading a heavy file if network get disconnected then FTP server acquires lock on file being uploaded, now when user tries to re upload the same file then it get access denied error.
I have set TimeOut and ReadWriteTimeOut to 5 secs of FtpWebRequest on FTP Server it is 10 secs.
Even if i try to upload same file after an Hour then also same problem exist.
// Get the object used to communicate with the server.
request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + FtpInfo.FtpServer.Trim() + "/" + FtpInfo.FtpFolderPath.Trim() + "/" + FileName.Trim()));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Proxy = null;
// FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(FtpInfo.UserNameForFTP.Trim(), FtpInfo.PasswordForFTP.Trim());
request.UsePassive = FtpInfo.UsePassive;
request.KeepAlive = FtpInfo.KeepAlive;
request.Timeout = FtpInfo.TimeOut; //Milliseconds
request.UseBinary = true;
request.ReadWriteTimeout = FtpInfo.TimeOut; //Milliseconds
FileInfo fi = new FileInfo(SourceLocation);
long length = fi.Length;
BytesUploaded = length;
long uploadSize = 0;
if (chunks == 0)
{
chunks = 1024;
}
else
{
buffLength = chunks;
}
byte[] buff = new byte[buffLength];
int contentLen;
using (FileStream fs = fi.OpenRead())
{
using (Stream strm = request.GetRequestStream())
{
contentLen = fs.Read(buff, 0, buffLength);
try
{
while (contentLen != 0)
{
Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() { lblProgress.Content = "Uploading '" + FileName + "'......" + "Bytes Uploaded (" + uploadSize.ToString() + "/" + length.ToString() + ")"; });
strm.Write(buff, 0, contentLen);
uploadSize += contentLen;
contentLen = fs.Read(buff, 0, buffLength);
}
strm.Close();
}
catch (Exception ex)
{
if (strm!=null)
{
try
{
strm.Close();
}
catch
{
throw ex;
}
}
throw ex;
}
}
fs.Close();
}
try
{
//requestStream.Close(); -orignal
fi = null;
request=null;
}
catch { }
I don't know enough about your app (is the FTP upload on a separate thread for example) but try this:
bool DoneOK = false;
FtpWebRequest request = null;
FtpWebResponse response = null;
try {
// Get the object used to communicate with the server.
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" + FtpInfo.FtpServer.Trim() + "/" + FtpInfo.FtpFolderPath.Trim() + "/" + FileName.Trim()));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Proxy = null;
// FTP site uses anonymous logon.
request.Credentials = new NetworkCredential(FtpInfo.UserNameForFTP.Trim(), FtpInfo.PasswordForFTP.Trim());
request.UsePassive = FtpInfo.UsePassive;
request.KeepAlive = FtpInfo.KeepAlive;
request.Timeout = FtpInfo.TimeOut; //Milliseconds
request.UseBinary = true;
request.ReadWriteTimeout = FtpInfo.TimeOut; //Milliseconds
long length = new FileInfo(SourceLocation).Length;
long uploadSize = 0;
if ( chunks < 1 )
chunks = 1024;
buffLength = chunks;
byte[] buff = new byte[buffLength];
int contentLen = 0;
string MSG = "";
using (FileStream fs = File.OpenRead (SourceLocation))
using (Stream strm = request.GetRequestStream())
{
while ((contentLen = fs.Read(buff, 0, buffLength)) > 0 )
{
MSG = "Uploading '" + FileName + "'......" + "Bytes Uploaded (" + uploadSize.ToString() + "/" + length.ToString() + ")";
string tmp_MSG = MSG;
Dispatcher.Invoke(DispatcherPriority.Normal, () => { lblProgress.Content = tmpMSG; });
strm.Write(buff, 0, contentLen);
uploadSize += contentLen;
};
strm.Close();
// necessary - the upload occurs really here !
response = (FtpWebResponse) request.GetResponse();
// check the response codes... for example FileActionOK...
if ( response.StatusCode == System.Net.FtpStatusCode.FileActionOK )
DoneOK = true;
response.Close(); response = null;
request = null;
}
}
catch
{
};
if ( request != null )
{
if ( response != null )
{
try { response.Close(); } catch {};
response = null;
}
if ( !DoneOK )
{
try { request.Abort (); } catch {};
}
request = null;
}
This was problem related to the FTP Server we were using, when we switched FTP server to IIS then everything worked smoothly.
Thanks for all the help

Categories

Resources