How can i upload to my ftp multiple files one by one ?

  • Thread starter Thread starter Chocolade1972
  • Start date Start date
C

Chocolade1972

Guest
Today i can upload files one by one each time a single file.

But now i want to upload some files togeather for example i select 5 files then it should upload the first file when finish then upload the second file ....untill the last one.


This is the code in form1:


using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Security.Cryptography;
using System.IO;

namespace FTP_ProgressBar
{
public partial class Form1 : Form
{

private string FtpAddress = "myftpaddress";
private string UserName = "myusername";
private string Password = "mypassword";

public Form1()
{
InitializeComponent();

this.Select();

txtHost.Text = FtpAddress;
txtUsername.Text = UserName;
txtPassword.Text = Password;

txtHost.ForeColor = txtHost.WaterMarkForeColor;
txtUsername.ForeColor = txtUsername.WaterMarkForeColor;
txtPassword.ForeColor = txtPassword.WaterMarkForeColor;
txtDir.ForeColor = txtDir.WaterMarkForeColor;
txtUploadFile.ForeColor = txtUploadFile.WaterMarkForeColor;

txtHost.TextChanged += anyTextBox_TextChanged;
txtUploadFile.TextChanged += anyTextBox_TextChanged;
txtDir.TextChanged += anyTextBox_TextChanged;

anyTextBox_TextChanged(null, null);

if ((txtHost.Text == "") || (txtUploadFile.Text == ""))
{
btnUpload.Enabled = false;
txtHost.WaterMark = "Enter ftp valid address";
txtUploadFile.WaterMark = "Select a file to upload";
}

if (txtDir.Text == "")
{
checkBox1.Enabled = false;
txtDir.WaterMark = "Enter a sub directory name(optinal)";
}

if (txtUsername.Text == "")
{
txtUsername.WaterMark = "Enter a username";
}


if (txtPassword.Text == "")
{
txtPassword.WaterMark = "Enter a password";
}

txtPassword.PasswordChar = *;
}

private void anyTextBox_TextChanged(object sender, EventArgs e)
{
btnUpload.Enabled = txtHost.TextLength > 0 && txtUploadFile.TextLength > 0;
checkBox1.Enabled = txtDir.TextLength > 0;
this.Invalidate();
}

private void Form1_Load(object sender, EventArgs e)
{

}

private void btnBrowse_Click(object sender, EventArgs e)
{
openFileDialog1.Multiselect = true;
if (this.openFileDialog1.ShowDialog() != DialogResult.Cancel)
this.txtUploadFile.Text = this.openFileDialog1.FileName;
}

private void btnUpload_Click(object sender, EventArgs e)
{
if (txtDir.Text != null || txtDir.Text != "")
{
FtpProgress.d = new DirectoryInfo(txtDir.Text);
}
if(this.ftpProgress1.IsBusy)
{
this.ftpProgress1.CancelAsync();
this.btnUpload.Text = "Upload";
}
else
{
FtpSettings f = new FtpSettings();
f.Host = this.txtHost.Text;
f.Username = this.txtUsername.Text;
f.Password = this.txtPassword.Text;
f.TargetFolder = this.txtDir.Text;
f.SourceFile = this.txtUploadFile.Text;
f.Passive = this.chkPassive.Checked;
try
{
f.Port = Int32.Parse(this.txtPort.Text);
}
catch { }
this.toolStripProgressBar1.Visible = true;
this.ftpProgress1.RunWorkerAsync(f);
this.btnUpload.Text = "Cancel";
}
}

private void ftpProgress1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.toolStripStatusLabel1.Text = e.UserState.ToString(); // the message will be something like: 45 Kb / 102.12 Mb
this.toolStripProgressBar1.Value = Math.Min(this.toolStripProgressBar1.Maximum, e.ProgressPercentage);
}

private void ftpProgress1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Error != null)
MessageBox.Show(e.Error.ToString(), "FTP error");
else if(e.Cancelled)
this.toolStripStatusLabel1.Text = "Upload Cancelled";
else
this.toolStripStatusLabel1.Text = "Upload Complete";
this.btnUpload.Text = "Upload";
this.toolStripProgressBar1.Visible = true;
}

private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
txtPassword.PasswordChar = checkBox1.Checked ? * : \0;
}
else
{
txtPassword.PasswordChar = *;
}
}
}
}


Some information:


txtHost is a textBox for the ftp address.

txtUsername for username.

txtPassword for password.

txtDir for directory.

txtUploadFile for file.

All this are textBoxes.


I added this part:


if (txtDir.Text != null || txtDir.Text != "")
{
FtpProgress.d = new DirectoryInfo(txtDir.Text);
}


d is DirectoryInfo


Now the class of where im doing the uploading:


using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;

namespace FTP_ProgressBar
{
public partial class FtpProgress : BackgroundWorker
{
public static string ConnectionError;
public static DirectoryInfo d;
public static string ftp;
private FtpSettings f;
private FileInfo[] flist;

public FtpProgress()
{
InitializeComponent();
}

public FtpProgress(IContainer container)
{
container.Add(this);
InitializeComponent();
}

private void FtpProgress_DoWork(object sender, DoWorkEventArgs e)
{
try
{
flist = d.GetFiles();
if (flist.GetLength(0) > 0)
{
foreach (FileInfo txf in flist)
{
string fn = txf.FullName;
BackgroundWorker bw = sender as BackgroundWorker;
f = e.Argument as FtpSettings;
string UploadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(fn));//f.SourceFile));
if (!UploadPath.ToLower().StartsWith("ftp://"))
UploadPath = "ftp://" + UploadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(UploadPath);
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = 300000;
request.Credentials = new NetworkCredential(f.Username, f.Password);
long FileSize = new FileInfo(f.SourceFile).Length;
string FileSizeDescription = GetFileSize(FileSize);
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
long SentBytes = 0;
byte[] Buffer = new byte[ChunkSize];
using (Stream requestStream = request.GetRequestStream())
{
using (FileStream fs = File.Open(f.SourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
int BytesRead = fs.Read(Buffer, 0, ChunkSize);
while (BytesRead > 0)
{
try
{
if (bw.CancellationPending)
return;

requestStream.Write(Buffer, 0, BytesRead);

SentBytes += BytesRead;

string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(SentBytes), FileSizeDescription);
bw.ReportProgress((int)(((decimal)SentBytes / (decimal)FileSize) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
fs.Position -= BytesRead;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
BytesRead = fs.Read(Buffer, 0, ChunkSize);
}
}
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("Upload File Complete, status {0}", response.StatusDescription));
}
}
}
catch (WebException ex)
{
switch (ex.Status)
{
case WebExceptionStatus.NameResolutionFailure:
ConnectionError = "Error: Please check the ftp address";
break;
case WebExceptionStatus.Timeout:
ConnectionError = "Error: Timout Request";
break;
}
}
}



public static string GetFileSize(long numBytes)
{
string fileSize = "";

if (numBytes > 1073741824)
fileSize = String.Format("{0:0.00} Gb", (double)numBytes / 1073741824);
else if (numBytes > 1048576)
fileSize = String.Format("{0:0.00} Mb", (double)numBytes / 1048576);
else
fileSize = String.Format("{0:0} Kb", (double)numBytes / 1024);

if (fileSize == "0 Kb")
fileSize = "1 Kb";
return fileSize;
}
}

public class FtpSettings
{
public string Host, Username, Password, TargetFolder, SourceFile;
public bool Passive;
public int Port = 21;
}
}




It was working fine fo single file but i changed/added this part:

In the top of the class:


public static DirectoryInfo d;
private FileInfo[] flist;


Then i added the part:


foreach (FileInfo txf in flist)
{
string fn = txf.FullName;


And instead f.SourceFile i changed it to fn.

But im getting exception:

The remote server returned an error: (550) File unavailable (e.g., file not found, no access).


And it did work before the changes for a sing file.


What i want it to do now is like before upload each time a single file using the backgrounworker and progressBar just like before my changes but this time when it finish to upload the first file go to the backgroundworker completed event show the Completed message just like for a single file and then move on automatic to the next file and so on untill the last file in FileInfo[] in the FtpProgress class.


If files(FileInfo[]) contain 1 file upload one single file. If it contain 121 files upload all the 121 files one by one.


How can i do it ? What do i need to change/add to my code ?

Continue reading...
 
Back
Top