说明:.NET中内置的FtpWebRequest、FtpWebResponse类库来支持FTP的操作。
但是并不是很稳定,在代码中有说明,
如: FtpWebRequest ftpFileWRequest = GetFtpWebRequest(strUri, strUID, strPWD);
ftpFileWRequest.Timeout =250; //超时不能太长 否则界面假死
或许我还有需要有什么特性来支撑,保证稳定性。但是我始终没有发现,或许socket是最好的选择吧。因为目前公司项目里面使用socket做的FTP还是算比较稳定的。
这是08年研究的一个例子,贴出来,作为参考。
源代码:
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; using System.Text.RegularExpressions; using System.Threading; namespace WinFormUpload { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { textBoxServerIP.Text = "211.166.8.79/UploadServer"; textBoxUserID.Text = "123456"; textBoxPassWord.Text = "123456"; textBox1.Text="H://UploadFolderServer"; } delegate void CreateTreeView(string strPath, TreeNode treeNodeInstance); private string strUID; private string strPWD; private bool boolConnectionFtp; private void button1_Click(object sender, EventArgs e) { string strPath = string.Empty; folderBrowserDialog1.ShowNewFolderButton = true; if (folderBrowserDialog1.ShowDialog() != DialogResult.OK) { return; } strPath = folderBrowserDialog1.SelectedPath; textBox1.Text = strPath; treeView1.Nodes.Clear(); //顶级节点 TreeNode treeNodeTop = new TreeNode((new DirectoryInfo(strPath).Name)); treeView1.Nodes.Add(treeNodeTop); //匿名方法 //CreateTreeView delegateCTV = delegate(string strPaths, TreeNode treeNodeInstance) //{ // DirectoryInfo dirinfo = new DirectoryInfo(strPaths); // //获得所有子目录 // foreach (DirectoryInfo dirinfoChildren in dirinfo.GetDirectories()) // { // TreeNode treeNodeInstanceChildren = new TreeNode(dirinfoChildren.Name); // //递归调用,遍历所有文件夹 //注:匿名方法不能递归调用 (错误信息:使用了未赋值的局部变量“delegateCTV”) // delegateCTV(strPaths+"//"+dirinfoChildren.Name, treeNodeInstanceChildren); // //向父节点添加子节点 // treeNodeInstance.Nodes.Add(treeNodeInstanceChildren); // } // //将节点对象添加到数中 // // treeView1.Nodes.Add(treeNodeInstance); //}; //delegateCTV(strPath, treeNodeTop); //实例化委托 CreateTreeView ctv = new CreateTreeView(CreateTreeNode); //treeView1.BeginUpdate(); //绘制之前显示为等待光标 Cursor.Current = Cursors.WaitCursor; //委托调用 ctv(strPath,treeNodeTop); // treeView1.EndUpdate(); Cursor.Current = Cursors.Default; } private void CreateTreeNode(string strPaths, TreeNode treeNodeInstance) { DirectoryInfo dirinfo = new DirectoryInfo(strPaths); //获得每一层的所有子目录 foreach (FileSystemInfo fsinfoChildren in dirinfo.GetFileSystemInfos()) //.GetDirectories()获取所有文件夹 { TreeNode treeNodeInstanceChildren = new TreeNode(fsinfoChildren.Name); //treeNodeInstanceChildren.Tag = fsinfoChildren.FullName; //无法实现鼠标放在节点上面显示信息的功能 // ToolTip ttip = new ToolTip(); ttip.SetToolTip((Control)treeNodeInstanceChildren, fsinfoChildren.FullName); //treeNodeInstanceChildren.ToolTipText = fsinfoChildren.FullName; //向父节点添加子节点 treeNodeInstance.Nodes.Add(treeNodeInstanceChildren); //判断是否是文件夹 if (! new DirectoryInfo(fsinfoChildren.FullName).Exists) continue; //递归调用,遍历所有文件夹 //路径参数使用strPaths + "//" + dirinfoChildren.Name 也可以 CreateTreeNode(fsinfoChildren.FullName, treeNodeInstanceChildren); } } private void button2_Click(object sender, EventArgs e) { treeView1.ExpandAll(); } private void button3_Click(object sender, EventArgs e) { treeView1.CollapseAll(); } private void button4_Click(object sender, EventArgs e) { folderBrowserDialog2.ShowNewFolderButton = true; if (folderBrowserDialog2.ShowDialog() != DialogResult.OK) return; textBox2.Text = folderBrowserDialog2.SelectedPath; } private void button5_Click(object sender, EventArgs e) { if (!boolConnectionFtp) { MessageBox.Show("请连接FTP服务器之后再执行上传操作!"); return; } string strFromPath = textBox1.Text; string strToPath = textBox2.Text; if (!new DirectoryInfo(strFromPath).Exists) { MessageBox.Show("源文件夹地址不存在!"); return; } //if (!new DirectoryInfo(strToPath).Exists) //{ // MessageBox.Show("目标文件夹地址不存在!"); // return; // } //假如输入的HTTP协议目标文件夹后面与“/”则删除,方便后面递归遍历文件夹 if (strToPath.EndsWith("/")) strToPath=strToPath.Remove(strToPath.Length-1); //创建上传控件 WebClient uploadFileWClient = new WebClient(); uploadFileWClient.Credentials = CredentialCache.DefaultNetworkCredentials; UploadFolder(uploadFileWClient,strFromPath, strToPath); uploadFileWClient.Dispose(); richTextBox1.AppendText("传输完成!"); richTextBox1.AppendText("/r/n"); } //单个文件的传输 private void UploadFile( WebClient uploadFileWClient,string strFromPath,string strToPath) { if (!strToPath.EndsWith("/")) strToPath = strToPath + "/"; //获得上传到服务器的文件的路径 string strToPathFile = strToPath + strFromPath.Substring(strFromPath.LastIndexOf("//")+1); //上传文件 FileStream fs = new FileStream(strFromPath, FileMode.Open,FileAccess.Read); if (boolHaveFile(fs,strToPath)) return; BinaryReader br = new BinaryReader(fs); try { byte[] filebytes = br.ReadBytes((int)fs.Length); //用流传输数据 Stream uploadStream = uploadFileWClient.OpenWrite(strToPathFile, "PUT"); //服务器是否支持写的操作 if (uploadStream.CanWrite) { richTextBox1.AppendText("正在上传文件..."); richTextBox1.AppendText("/r/n"); richTextBox1.AppendText("源文件:" + strFromPath + "->服务器文件:" + strToPathFile); richTextBox1.AppendText("/r/n"); uploadStream.Write(filebytes, 0, filebytes.Length); richTextBox1.AppendText("上传成功!"); richTextBox1.AppendText("/r/n"); } else { richTextBox1.AppendText("上传文件:" + strFromPath + "到服务器:" + strToPathFile + "->失败!错误原因:目标服务器不支持写操作!"); richTextBox1.AppendText("/r/n"); } fs.Close(); uploadStream.Close(); } catch(WebException ex) { richTextBox1.AppendText("上传文件失败!错误信息:"+ex.Message+"/n/r"); } } //判断服务器文件是否存在 private bool boolHaveFile(FileStream fs, string strToPathFile) { //if (((HttpWebResponse)(((HttpWebRequest)WebRequest.Create(strToPathFile)).GetResponse())).ContentLength !=0) //try //{ // HttpWebResponse httpwResponse = (HttpWebResponse)(((HttpWebRequest)WebRequest.Create(strToPathFile)).GetResponse()); // if (httpwResponse.StatusCode == HttpStatusCode.OK) // { // if (httpwResponse.ContentLength == fs.Length) // { // richTextBox1.AppendText("目标文件" + strToPathFile + "存在,已跳过!"); // richTextBox1.AppendText("/r/n"); // return true; // } // else // { // richTextBox1.AppendText("目标文件" + strToPathFile + "存在,但不是最新版本,覆盖中..."); // richTextBox1.AppendText("/r/n"); // return false; // } // } // return false; //} //catch { return false; } try { HttpWebRequest hwr= (HttpWebRequest)WebRequest.Create(strToPathFile); hwr.Timeout = 250; HttpWebResponse httpwResponse = (HttpWebResponse)((hwr).GetResponse()); if (httpwResponse.StatusCode == HttpStatusCode.OK) { if (httpwResponse.ContentLength == fs.Length) { richTextBox1.AppendText("目标文件" + strToPathFile + "存在,已跳过!"); richTextBox1.AppendText("/r/n"); return true; } else { richTextBox1.AppendText("目标文件" + strToPathFile + "存在,但不是最新版本,覆盖中..."); richTextBox1.AppendText("/r/n"); return false; } } return false; } catch { return false; } } //文件夹的传输 private void UploadFolder(WebClient uploadFileWClient, string strFromPath, string strToPath) { foreach (FileSystemInfo fsinfoChildren in (new DirectoryInfo(strFromPath)).GetFileSystemInfos()) { //本地文件夹路径 string strPath = fsinfoChildren.FullName; if (new DirectoryInfo(strPath).Exists) { // 如果是文件夹就服务器上面创建文件夹,,递归到下一层文件夹 CreateFolder(fsinfoChildren.Name, strToPath); UploadFolder(uploadFileWClient, strPath, strToPath + "/" + fsinfoChildren.Name); } else {//如果是文件就直接上传到服务器 UploadFile(uploadFileWClient, strPath, strToPath); continue; } } } //在服务器上面创建文件夹 private void CreateFolder(string strFromFolderName, string strToPath) { FtpWebRequest ftpFileWRequest; try { string strUri = strToPath + "/" + strFromFolderName ; if (Regex.IsMatch(strUri, @"^[Hh]{1}[Tt]{2}[Pp]{1}/://")) { strUri = Regex.Replace(strUri, @"^[Hh]{1}[Tt]{2}[Pp]{1}/://", @""); } if (IsHaveFolder( strUri, strUID, strPWD)) return; //发送创建文件夹命令 ftpFileWRequest = GetFtpWebRequest(strUri, strUID, strPWD); ftpFileWRequest.Method = WebRequestMethods.Ftp.MakeDirectory; FtpWebResponse ftpwResponse = (FtpWebResponse)ftpFileWRequest.GetResponse(); richTextBox1.AppendText("创建文件夹"+strFromFolderName+"成功!状态信息:"+ftpwResponse.StatusDescription+"/r/n"); //StreamReader sr = new StreamReader(ftpwResponse.GetResponseStream(), System.Text.Encoding.Default); //while (!sr.EndOfStream) //{ // richTextBox1.AppendText(sr.ReadLine() + "/r/n"); //} //sr.Close(); ftpwResponse.Close(); }catch(WebException ex){ richTextBox1.AppendText("创建文件夹"+strFromFolderName+"失败!错误信息:"+ex.Message+"/r/n"); } } //判断文件夹是否存在 private bool IsHaveFolder(string strUri, string strUID, string strPWD) { try { FtpWebRequest ftpFileWRequest = GetFtpWebRequest(strUri, strUID, strPWD); ftpFileWRequest.Timeout =250; //超时不能太长 否则界面假死 ftpFileWRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; long longFileLength = ((FtpWebResponse)ftpFileWRequest.GetResponse()).ContentLength; if (longFileLength != 0) { richTextBox1.AppendText("目标文件夹" + strUri + "存在,已跳过!"); richTextBox1.AppendText("/r/n"); return true; } return false; } catch { return false; } } private void textBoxServerIP_TextChanged(object sender, EventArgs e) { textBox2.Text = "Http://" + textBoxServerIP.Text; } private void button6_Click(object sender, EventArgs e) { richTextBox1.AppendText("正在连接FTP服务器(" + textBoxServerIP.Text + ")..."); richTextBox1.AppendText("/r/n"); ConnectionFtpServer(textBoxServerIP.Text,textBoxUserID.Text,textBoxPassWord.Text); } //登录FTP服务器 private void ConnectionFtpServer(string ServerIP, string UID, string PWD) { //WebClient控件不能实现创建文件功能 这里使用FtpWebRequest控件实现 try { //验证登录信息 FtpWebRequest ftpFileWRequest = GetFtpWebRequest(ServerIP, UID, PWD); //目录下面的详细列表 ftpFileWRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails; FtpWebResponse ftpwResponse = (FtpWebResponse)ftpFileWRequest.GetResponse(); //第一次连接成功后保存FTP帐户信息 strUID = UID; strPWD = PWD; boolConnectionFtp = true; richTextBox1.AppendText(ftpwResponse.BannerMessage); richTextBox1.AppendText("/r/n"); richTextBox1.AppendText("连接状态码信息:" + ftpwResponse.StatusDescription); richTextBox1.AppendText("/r/n"); richTextBox1.AppendText("连接服务器成功!"); richTextBox1.AppendText("/r/n"); //读取文件夹下面的详细列表信息,编码格式System.Text.Encoding.Default StreamReader sr = new StreamReader(ftpwResponse.GetResponseStream(),System.Text.Encoding.Default); richTextBox1.AppendText("服务器目录下面的详细列表:" + "/r/n"); while (!sr.EndOfStream) { richTextBox1.AppendText(sr.ReadLine() + "/r/n"); } sr.Close(); ftpwResponse.Close(); }catch (WebException ex){ richTextBox1.AppendText("连接服务器失败!错误信息:" + ex.Message); richTextBox1.AppendText("/r/n"); } } //每次发送FTP命令的时候创建一个新的FtpWebRequest对象 private FtpWebRequest GetFtpWebRequest(string ServerIP, string UID, string PWD) { UriBuilder uburi = new UriBuilder(); uburi.Scheme = "ftp";//FTP路径最后一个字符不能为“/” uburi.Host = ServerIP; Uri myuri = uburi.Uri; //if (myuri.Scheme != Uri.UriSchemeFtp) //{ // return null; //} FtpWebRequest ftpFileWRequest = (FtpWebRequest)WebRequest.Create(myuri); ftpFileWRequest.UseBinary = true; ftpFileWRequest.KeepAlive = true ; //设置登录凭证信息 ftpFileWRequest.Credentials = new NetworkCredential(UID, PWD); return ftpFileWRequest; } ////滚动条滚动到最底端 //private void ScrollBottom() { // richTextBox1.Focus(); // richTextBox1.Select(richTextBox1.Text.Length, 0); // richTextBox1.ScrollToCaret(); //} } }
Desinger文件源代码:
namespace WinFormUpload { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.treeView1 = new System.Windows.Forms.TreeView(); this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); this.button1 = new System.Windows.Forms.Button(); this.textBox1 = new System.Windows.Forms.TextBox(); this.button2 = new System.Windows.Forms.Button(); this.button3 = new System.Windows.Forms.Button(); this.richTextBox1 = new System.Windows.Forms.RichTextBox(); this.button4 = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.button5 = new System.Windows.Forms.Button(); this.folderBrowserDialog2 = new System.Windows.Forms.FolderBrowserDialog(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); this.textBoxServerIP = new System.Windows.Forms.TextBox(); this.textBoxUserID = new System.Windows.Forms.TextBox(); this.textBoxPassWord = new System.Windows.Forms.TextBox(); this.button6 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // treeView1 // this.treeView1.Location = new System.Drawing.Point(12, 12); this.treeView1.Name = "treeView1"; this.treeView1.Size = new System.Drawing.Size(285, 343); this.treeView1.TabIndex = 0; // // button1 // this.button1.Location = new System.Drawing.Point(605, 401); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 1; this.button1.Text = "浏览"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(312, 401); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(261, 21); this.textBox1.TabIndex = 2; // // button2 // this.button2.Location = new System.Drawing.Point(312, 262); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(75, 23); this.button2.TabIndex = 3; this.button2.Text = "展开全部"; this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // // button3 // this.button3.Location = new System.Drawing.Point(312, 331); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(75, 23); this.button3.TabIndex = 4; this.button3.Text = "折叠全部"; this.button3.UseVisualStyleBackColor = true; this.button3.Click += new System.EventHandler(this.button3_Click); // // richTextBox1 // this.richTextBox1.Location = new System.Drawing.Point(514, 12); this.richTextBox1.Name = "richTextBox1"; this.richTextBox1.Size = new System.Drawing.Size(342, 343); this.richTextBox1.TabIndex = 5; this.richTextBox1.Text = ""; // // button4 // this.button4.Location = new System.Drawing.Point(605, 450); this.button4.Name = "button4"; this.button4.Size = new System.Drawing.Size(75, 23); this.button4.TabIndex = 6; this.button4.Text = "浏览"; this.button4.UseVisualStyleBackColor = true; this.button4.Click += new System.EventHandler(this.button4_Click); // // textBox2 // this.textBox2.Location = new System.Drawing.Point(312, 452); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(261, 21); this.textBox2.TabIndex = 7; // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(256, 401); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(41, 12); this.label1.TabIndex = 8; this.label1.Text = "FROM:"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(258, 450); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(29, 12); this.label2.TabIndex = 9; this.label2.Text = "To:"; // // button5 // this.button5.Location = new System.Drawing.Point(711, 452); this.button5.Name = "button5"; this.button5.Size = new System.Drawing.Size(112, 23); this.button5.TabIndex = 10; this.button5.Text = "上传"; this.button5.UseVisualStyleBackColor = true; this.button5.Click += new System.EventHandler(this.button5_Click); // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(12, 371); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(59, 12); this.label3.TabIndex = 11; this.label3.Text = "FTPServer"; // // label4 // this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(12, 401); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(53, 12); this.label4.TabIndex = 12; this.label4.Text = "SeverIP:"; // // label5 // this.label5.AutoSize = true; this.label5.Location = new System.Drawing.Point(10, 450); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(47, 12); this.label5.TabIndex = 13; this.label5.Text = "UserID:"; // // label6 // this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(10, 490); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(59, 12); this.label6.TabIndex = 14; this.label6.Text = "PassWord:"; // // textBoxServerIP // this.textBoxServerIP.Location = new System.Drawing.Point(71, 398); this.textBoxServerIP.Name = "textBoxServerIP"; this.textBoxServerIP.Size = new System.Drawing.Size(143, 21); this.textBoxServerIP.TabIndex = 15; this.textBoxServerIP.TextChanged += new System.EventHandler(this.textBoxServerIP_TextChanged); // // textBoxUserID // this.textBoxUserID.Location = new System.Drawing.Point(71, 440); this.textBoxUserID.Name = "textBoxUserID"; this.textBoxUserID.Size = new System.Drawing.Size(143, 21); this.textBoxUserID.TabIndex = 16; // // textBoxPassWord // this.textBoxPassWord.Location = new System.Drawing.Point(71, 481); this.textBoxPassWord.Name = "textBoxPassWord"; this.textBoxPassWord.Size = new System.Drawing.Size(143, 21); this.textBoxPassWord.TabIndex = 17; // // button6 // this.button6.Location = new System.Drawing.Point(71, 520); this.button6.Name = "button6"; this.button6.Size = new System.Drawing.Size(75, 23); this.button6.TabIndex = 18; this.button6.Text = "连接"; this.button6.UseVisualStyleBackColor = true; this.button6.Click += new System.EventHandler(this.button6_Click); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(868, 577); this.Controls.Add(this.button6); this.Controls.Add(this.textBoxPassWord); this.Controls.Add(this.textBoxUserID); this.Controls.Add(this.textBoxServerIP); this.Controls.Add(this.label6); this.Controls.Add(this.label5); this.Controls.Add(this.label4); this.Controls.Add(this.label3); this.Controls.Add(this.button5); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.textBox2); this.Controls.Add(this.button4); this.Controls.Add(this.richTextBox1); this.Controls.Add(this.button3); this.Controls.Add(this.button2); this.Controls.Add(this.textBox1); this.Controls.Add(this.button1); this.Controls.Add(this.treeView1); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.TreeView treeView1; private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button3; private System.Windows.Forms.RichTextBox richTextBox1; private System.Windows.Forms.Button button4; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Button button5; private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog2; private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox textBoxServerIP; private System.Windows.Forms.TextBox textBoxUserID; private System.Windows.Forms.TextBox textBoxPassWord; private System.Windows.Forms.Button button6; } }