ftp:是一种协议,文件传输协议。ftp的主要作用,就是让用户连接一个远程计算机查看远程计算机有哪些文件,然后把文件从远程计算机上拷贝到本地计算机,或者把本地文件发送到远程计算机上。文件的发送与接受都是以流的方式进行的。
本篇博文主要介绍winform上ftp对图片的上传和下载以及进度条对应的显示。进度条主要是为了让用户知道图片上传了多少,还有多久上传完成,以及是否上传完成。下载图片也还是一样的效果。
首先看一下界面运行后的结果:
先贴上底层类的方法:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Windows.Forms; using System.Configuration; using System.Drawing; namespace WinformFTP { public class FTPTools {
//创建请求对象。 private static FtpWebRequest GetRequest(string URI, string username, string password) { FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI); result.Credentials = new System.Net.NetworkCredential(username, password); result.KeepAlive = false; return result; } //Ftp路径 static string FtpUrl { get { return ConfigurationManager.ConnectionStrings["FtpUrl"].ToString(); } } //Ftp文件件 static string BusinessCard { get { return ConfigurationManager.ConnectionStrings["FtpFolder"].ToString(); } } //上传图片的方法。 public void uploadPicture(string path, ProgressBar proImage, PictureBox picImage, Label lblPro, Label lblDate, Label lblState, Label lblSpeed) { if (!string.IsNullOrEmpty(path) && File.Exists(path)) { FileInfo file = new FileInfo(path); int j = file.Name.LastIndexOf('.'); string filename = Guid.NewGuid().ToString(); string fullname = filename + file.Name.Substring(j, 4);//获取文件名 和 后缀名 UploadFile(file, fullname, "", "", proImage, picImage, lblPro, lblDate, lblState, lblSpeed, path); } } //时间。 private string strDate; /// <summary> /// 上传文件 /// </summary> /// <param name="fileinfo">需要上传的文件</param> /// <param name="targetDir">目标路径</param> /// <param name="hostname">ftp地址</param> /// <param name="username">ftp用户名</param> /// <param name="password">ftp密码</param> private void UploadFile(FileInfo fileinfo, string filename, string username, string password, ProgressBar proImage, PictureBox picImage, Label lblPro, Label lblDate, Label lblState, Label lblSpeed, string path) { if (BusinessCard.Trim() == "") { return; } proImage.Value = 0; string URI = "FTP://" + FtpUrl + "/" + BusinessCard + "/" + filename; System.Net.FtpWebRequest ftp = GetRequest(URI, username, password); //设置FTP命令 ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile; ftp.UseBinary = true; ftp.UsePassive = true; //告诉ftp文件大小 ftp.ContentLength = fileinfo.Length; const int BufferSize = 2048; byte[] content = new byte[BufferSize]; int dataRead = 0; //上传文件内容 using (FileStream fs = fileinfo.OpenRead()) { try { using (Stream rs = ftp.GetRequestStream()) { //已上传的字节数 long offset = 0; long length = fs.Length; DateTime startTime = DateTime.Now; proImage.Maximum = int.MaxValue; do { offset += dataRead; proImage.Value = (int)(offset * (int.MaxValue / length)); TimeSpan span = DateTime.Now - startTime; double second = span.TotalSeconds; lblPro.Text = lblDate.Text = lblState.Text = lblSpeed.Text = ""; strDate = second.ToString("F2") + "秒"; lblDate.Text = "已用时:" + second.ToString("F2") + "秒"; if (second > 0.001) { lblSpeed.Text = "平均速度:" + (offset / 1024 / second).ToString("0.00") + "KB/秒"; } else { lblSpeed.Text = "正在连接…"; } lblState.Text = "已上传:" + (offset * 100.0 / length).ToString("F2") + "% "; lblPro.Text = "图片大小:" + (offset / 1048576.0).ToString("F2") + "M/" + (length / 1048576.0).ToString("F2") + "M"; dataRead = fs.Read(content, 0, BufferSize); rs.Write(content, 0, dataRead); } while (dataRead > 0); lblDate.Text = "已用时:" + strDate; picImage.Image = Image.FromFile(path); rs.Close(); } } catch (Exception ex) { } finally { fs.Close(); } } ftp = null; }
//下载图片处理。 public void DownloadFile(string localDir, string FtpDir, string FtpFile, string hostname, string username, string password, ProgressBar proImage, Label lblPro, PictureBox picImage) { float percent = 0; string URI = "FTP://" + hostname + "/" + FtpDir + "/" + FtpFile; string tmpname = Guid.NewGuid().ToString(); string localfile = localDir + @"\" + FtpFile; FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(URI); request.Credentials = new System.Net.NetworkCredential(username, password); request.Method = WebRequestMethods.Ftp.GetFileSize; long totalBytes = 0; using (FtpWebResponse rep = (FtpWebResponse)request.GetResponse()) { totalBytes = rep.ContentLength; } System.Net.FtpWebRequest ftp = GetRequest(URI, username, password); ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile; ftp.UseBinary = true; using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse()) { using (Stream responseStream = response.GetResponseStream()) { if (!Directory.Exists(localDir)) { Directory.CreateDirectory(localDir); } using (FileStream fs = new FileStream(localfile, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { try { if (proImage != null) { proImage.Maximum = (int)totalBytes; } long totalDownloadedByte = 0; byte[] buffer = new byte[2048]; int read = 0; lblPro.Text = "下载图片正在加载......"; do { totalDownloadedByte += read; if (proImage != null) { proImage.Value = (int)totalDownloadedByte; } read = responseStream.Read(buffer, 0, buffer.Length); fs.Write(buffer, 0, read); percent = (float)totalDownloadedByte / (float)totalBytes * 100; lblPro.Text = ""; lblPro.Text = "当前图片下载进度" + percent.ToString() + "%"; } while (read > 0); if ((int)percent == 100) { picImage.Image = Image.FromStream(fs); } fs.Flush(); fs.Close(); } catch (Exception) { fs.Close(); File.Delete(localfile); throw; } } File.Delete(localfile); responseStream.Close(); } response.Close(); } ftp = null; } } }
其中要注意,下载方法DownloadFile中的代码。下载图片到的处理是,从远程服务器上获得流,再把流绑定到PictureBox控件上( picImage.Image =Image.FromStream(fs);)。这就说明要远程服务器要返回流。因为同时要让进度条ProgressBar 控件反应下载的进度。所以也要获得下载图片的大小(rep.ContentLength),也许有人说这有什么难的,直接把他们都返回就是的了,关键是一次不能返回。原因如下:
ContentLength - 设置这个属性对于ftp服务器是有用的,但是客户端不使用它,因为FtpWebRequest忽略这个属性,所以在这种情况下,该属性是无效的。但是如果 我们设置了这个属性,ftp服务器将会提前预知文件的大小(在upload时会有这种情况)
所以我上面就只能请求两次了,这是最纠结我的地方,我试了很多方法,都不行,最后也只能用这一种方法了。上传的应该没有什么好说的,看代码就可以懂的。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Configuration; using System.IO; using System.Net; using System.Threading; namespace WinformFTP { public partial class FrmFtp : Form { //图片名称。 public string path; //图片大小。 public long ImageLength; public FrmFtp() { InitializeComponent(); } //下载图片方法 private string loadPicture(string path) { FileInfo file = new FileInfo(path); int j = file.Name.LastIndexOf('.'); string filename = Guid.NewGuid().ToString(); string fullname = filename + file.Name.Substring(j, 4);//获取文件名 和 后缀名 string uri = String.Format("FTP://{0}/{1}/{2}", ConfigurationManager.ConnectionStrings["FtpUrl"].ToString(), ConfigurationManager.ConnectionStrings["FtpFolder"].ToString(), fullname); return uri; } //上传图片。 private void btnFtp_Click(object sender, EventArgs e) { this.picImage.Image = null; Thread thread = new Thread(new ThreadStart(GetImage)); thread.SetApartmentState(ApartmentState.STA); Control.CheckForIllegalCrossThreadCalls = false; thread.Start(); } //筛选图片。 private void GetImage() { openFileDialog1.FileName = string.Empty; openFileDialog1.Filter = "图片(jpg,bmp,png,jpeg)|*.JPG;*.PNG;*.BMP;*.JPEG"; openFileDialog1.InitialDirectory = @"c:\windows\ "; openFileDialog1.Multiselect = false; openFileDialog1.AddExtension = true; openFileDialog1.DereferenceLinks = true; openFileDialog1.CheckFileExists = true; openFileDialog1.CheckPathExists = true; if (openFileDialog1.ShowDialog() == DialogResult.OK) { if (openFileDialog1.FileName != string.Empty) { path = openFileDialog1.FileName; txtImage.Text = path; lblState.Text = "图片正在加载......."; FTPTools ftpTools = new FTPTools(); ftpTools.uploadPicture(path, proImage, picImage, lblPro, lblDate, lblState, lblSpeed); } } } //根据图片名称下载图片。 private void btnDownload_Click(object sender, EventArgs e) { new Thread(new ThreadStart(DownloadMyImage)).Start(); } //下载图片。 private void DownloadMyImage() { if (string.IsNullOrWhiteSpace(txtImage.Text)) { MessageBox.Show("请填写图片的名称,以下载图片!"); return; } if (IsExists(txtImage.Text)) { this.picImage.Image = null; path = loadPicture(txtImage.Text); if (!string.IsNullOrWhiteSpace(path)) { this.picImage.Image = null; this.proImage.Value = 0; FTPTools ftpTools = new FTPTools(); ftpTools.DownloadFile(@"C:\myImages", "BusinessCard", txtImage.Text, "119.254.69.18:29", "", "", proImage, lblPro, picImage); } } } //// 获取FTP图片文件是否存在 public static bool IsExists(string fileName) { List<string> list = FTPTools.ListDirectory(ConfigurationManager.ConnectionStrings["FtpFolder"].ToString(), ConfigurationManager.ConnectionStrings["FtpUrl"].ToString(), "", "", fileName); if (list == null) { return false; } else { return true; } } } }