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;
}
}
}
}