|
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;
///
/// 上传文件
///
/// 需要上传的文件
/// 目标路径
/// ftp地址
/// ftp用户名
/// ftp密码
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 list = FTPTools.ListDirectory(ConfigurationManager.ConnectionStrings["FtpFolder"].ToString(), ConfigurationManager.ConnectionStrings["FtpUrl"].ToString(), "", "", fileName);
if (list == null)
{
return false;
}
else
{
return true;
}
}
}
} |
|