转载 记录【C#操作FTP】
转自 http://t.zoukankan.com/mingjing-p-4516518.html
代码
不要忘记引入命名空间
using System.Net;
using System.IO;
下面的几个步骤包括了使用FtpWebRequest类实现ftp功能的一般过程
1、创建一个FtpWebRequest对象,指向ftp服务器的uri
2、设置ftp的执行方法(上传,下载等)
3、给FtpWebRequest对象设置属性(是否支持ssl,是否使用二进制传输等)
4、设置登录验证(用户名,密码)
5、执行请求
6、接收相应流(如果需要的话)
7、如果没有打开的流,则关闭ftp请求
开发任何ftp应用程序都需要一个相关的ftp服务器及它的配置信息。FtpWebRequest暴露了一些属性来设置这些信息。
接下来的代码示例了上传功能
首先设置一个uri地址,包括路径和文件名。这个uri被使用在FtpWebRequest实例中。
然后根据ftp请求设置FtpWebRequest对象的属性
其中一些重要的属性如下:
Credentials - 指定登录ftp服务器的用户名和密码。
KeepAlive - 指定连接是应该关闭还是在请求完成之后关闭,默认为true
UseBinary - 指定文件传输的类型。有两种文件传输模式,一种是Binary,另一种是ASCII。两种方法在传输时,字节的第8位是不同的。ASCII使用第8位作为错误控制,而Binary的8位都是有意义的。所以当你使用ASCII传输时要小心一些。简单的说,如果能用记事本读和写的文件用ASCII传输就是安全的,而其他的则必须使用Binary模式。当然使用Binary模式发送ASCII文件也是非常好的。
UsePassive - 指定使用主动模式还是被动模式。早先所有客户端都使用主动模式,而且工作的很好,而现在因为客户端防火墙的存在,将会关闭一些端口,这样主动模式将会失败。在这种情况下就要使用被动模式,但是一些端口也可能被服务器的防火墙封掉。不过因为ftp服务器需要它的ftp服务连接到一定数量的客户端,所以他们总是支持被动模式的。这就是我们为什么要使用被动模式的原意,为了确保数据可以正确的传输,使用被动模式要明显优于主动模式。(译者注:主动(PORT)模式建立数据传输通道是由服务器端发起的,服务器使用20端口连接客户端的某一个大于1024的端口;在被动(PASV)模式中,数据传输的通道的建立是由FTP客户端发起的,他使用一个大于1024的端口连接服务器的1024以上的某一个端口)
ContentLength - 设置这个属性对于ftp服务器是有用的,但是客户端不使用它,因为FtpWebRequest忽略这个属性,所以在这种情况下,该属性是无效的。但是如果我们设置了这个属性,ftp服务器将会提前预知文件的大小(在upload时会有这种情况)
Method - 指定当前请求是什么命令(upload,download,filelist等)。这个值定义在结构体WebRequestMethods.Ftp中。
1 private void Upload(string filename)
2 {
3 FileInfo fileInf = new FileInfo(filename);
4 string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
5 FtpWebRequest reqFTP;
6 // 根据uri创建FtpWebRequest对象
7 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));
8 // ftp用户名和密码
9 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
10 // 默认为true,连接不会被关闭
11 // 在一个命令之后被执行
12 reqFTP.KeepAlive = false;
13 // 指定执行什么命令
14 reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
15 // 指定数据传输类型
16 reqFTP.UseBinary = true;
17 // 上传文件时通知服务器文件的大小
18 reqFTP.ContentLength = fileInf.Length;
19 // 缓冲大小设置为2kb
20 int buffLength = 2048;
21 byte[] buff = new byte[buffLength];
22 int contentLen;
23 // 打开一个文件流 (System.IO.FileStream) 去读上传的文件
24 FileStream fs = fileInf.OpenRead();
25 try
26 {
27 // 把上传的文件写入流
28 Stream strm = reqFTP.GetRequestStream();
29 // 每次读文件流的2kb
30 contentLen = fs.Read(buff, 0, buffLength);
31 // 流内容没有结束
32 while (contentLen != 0)
33 {
34 // 把内容从file stream 写入 upload stream
35 strm.Write(buff, 0, contentLen);
36 contentLen = fs.Read(buff, 0, buffLength);
37 }
38 // 关闭两个流
39 strm.Close();
40 fs.Close();
41 }
42 catch (Exception ex)
43 {
44 MessageBox.Show(ex.Message, "Upload Error");
45 }
46 }
以上代码简单的示例了ftp的上传功能。创建一个指向某ftp服务器的FtpWebRequest对象,然后设置其不同的属性Credentials,KeepAlive,Method,UseBinary,ContentLength。
打开本地机器上的文件,把其内容写入ftp请求流。缓冲的大小为2kb,无论上传大文件还是小文件,这都是一个合适的大小。
1 private void Download(string filePath, string fileName)
2 {
3 FtpWebRequest reqFTP;
4 try
5 {
6 FileStream outputStream = new FileStream(filePath + "\" + fileName, FileMode.Create);
7 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileName));
8 reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
9 reqFTP.UseBinary = true;
10 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
11 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
12 Stream ftpStream = response.GetResponseStream();
13 long cl = response.ContentLength;
14 int bufferSize = 2048;
15 int readCount;
16 byte[] buffer = new byte[bufferSize];
17 readCount = ftpStream.Read(buffer, 0, bufferSize);
18 while (readCount > 0)
19 {
20 outputStream.Write(buffer, 0, readCount);
21 readCount = ftpStream.Read(buffer, 0, bufferSize);
22 }
23 ftpStream.Close();
24 outputStream.Close();
25 response.Close();
26 }
27 catch (Exception ex)
28 {
29 MessageBox.Show(ex.Message);
30 }
31 }
上面的代码实现了从ftp服务器上下载文件的功能。这不同于之前所提到的上传功能,下载需要一个响应流,它包含着下载文件的内容。这个下载的文件是在FtpWebRequest对象中的uri指定的。在得到所请求的文件后,通过FtpWebRequest对象的GetResponse()方法下载文件。它将把文件作为一个流下载到你的客户端的机器上。
注意:我们可以设置文件在我们本地机器上的存放路径和名称。
public string[] GetFileList()
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
FtpWebRequest reqFTP;
try
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/"));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
WebResponse response = reqFTP.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("
");
line = reader.ReadLine();
}
// to remove the trailing '
'
result.Remove(result.ToString().LastIndexOf('
'), 1);
reader.Close();
response.Close();
return result.ToString().Split('
');
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
downloadFiles = null;
return downloadFiles;
}
}
上面的代码示例了如何从ftp服务器上获得文件列表。uri指向ftp服务器的地址。我们使用StreamReader对象来存储一个流,文件名称列表通过“ ”分隔开,也就是说每一个文件名称都占一行。你可以使用StreamReader对象的ReadToEnd()方法来得到文件列表。上面的代码中我们用一个StringBuilder对象来保存文件名称,然后把结果通过分隔符分开后作为一个数组返回。我确定只是一个比较好的方法。
其他的实现如Rename,Delete,GetFileSize,FileListDetails,MakeDir等与上面的几段代码类似,就不多说了。
注意:实现重命名的功能时,要把新的名字设置给FtpWebRequest对象的RenameTo属性。连接指定目录的时候,需要在FtpWebRequest对象所使用的uri中指明。
需要注意的地方
你在编码时需要注意以下几点:
除非EnableSsl属性被设置成true,否作所有数据,包括你的用户名和密码都将明文发给服务器,任何监视网络的人都可以获取到你连接服务器的验证信息。如果你连接的ftp服务器提供了SSL,你就应当把EnableSsl属性设置为true。
如果你没有访问ftp服务器的权限,将会抛出SecurityException错误
发送请求到ftp服务器需要调用GetResponse方法。当请求的操作完成后,一个FtpWebResponse对象将返回。这个FtpWebResponse对象提供了操作的状态和已经从ftp服务器上下载的数据。FtpWebResponse对象的StatusCode属性提供了ftp服务器返回的最后的状态代码。FtpWebResponse对象的StatusDescription属性为这个状态代码的描述。
以下是寫好的一個類
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Net;
5 using System.IO;
6 using System.Windows.Forms;
7 using System.Globalization;
8 using System.Text.RegularExpressions;
9
10 namespace DSS.BLL
11 {
12 public class FTPLib
13 {
14 private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(FTPLib));
15
16 string ftpServerIP;
17 string ftpUserID;
18 string ftpPassword;
19 FtpWebRequest reqFTP;
20
21 public struct FileStruct
22 {
23 public string Flags;
24 public string Owner;
25 public string Group;
26 public bool IsDirectory;
27 public DateTime CreateTime;
28 public string Name;
29 }
30
31 public enum FileListStyle
32 {
33 UnixStyle,
34 WindowsStyle,
35 Unknown
36 }
37
38 //連接FTP
39 private void Connect(String path)
40 {
41 //根據URL創建FTP WebRequest物件
42 reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(path));
43
44 //指定數據傳輸類型
45 reqFTP.UseBinary = true;
46
47 //FTP用戶名和密碼
48 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
49 }
50
51 public FTPLib(string ftpServerIP, string ftpUserID, string ftpPassword)
52 {
53 this.ftpServerIP = ftpServerIP;
54
55 this.ftpUserID = ftpUserID;
56
57 this.ftpPassword = ftpPassword;
58 }
59
60 //下面的代碼示例了如何從FTP服務器上獲得文件列表
61 private string[] GetFileList(string path, string WRMethods)
62 {
63 string[] downloadFiles;
64 StringBuilder result = new StringBuilder();
65
66 try
67 {
68 Connect(path);
69
70 reqFTP.Method = WRMethods;
71
72 WebResponse response = reqFTP.GetResponse();
73
74 StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default); //中文文件名
75
76 string line = reader.ReadLine();
77
78 while (line != null)
79 {
80 result.Append(line);
81 result.Append("
");
82 line = reader.ReadLine();
83 }
84
85 // to remove the trailing '
'
86 result.Remove(result.ToString().LastIndexOf('
'), 1);
87
88 reader.Close();
89 response.Close();
90
91 return result.ToString().Split('
');
92 }
93
94 catch (Exception ex)
95 {
96 System.Windows.Forms.MessageBox.Show(ex.Message);
97
98 downloadFiles = null;
99
100 return downloadFiles;
101 }
102 }
103
104 //下面的代碼實現了從FTP服務器上傳文件的功u-32515 能
105 public bool Upload(string filename, string newfilename, string dirname)
106 {
107 bool retValue = false;
108
109 try
110 {
111 FileInfo fileInf = new FileInfo(filename);
112
113 //文件名稱為上傳文件原來的名稱
114 //string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
115
116 //上傳文件名稱改為新的文件名稱
117 string uri = "ftp://" + ftpServerIP + "/" + dirname + "/" + newfilename;
118
119 //連接
120 Connect(uri);
121
122 //默認為TRUE,連接不會被關閉
123 //在一個命令之後被執行
124 reqFTP.KeepAlive = false;
125
126 //執行什麼命令
127 reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
128
129 //上傳文件時通知服務器文件的大小
130 reqFTP.ContentLength = fileInf.Length;
131
132 //緩衝大小設置為kb
133 int buffLength = 2048;
134 byte[] buff = new byte[buffLength];
135
136 int contentLen;
137
138 //打開一個文件流(System.IO.FileStream)去讀取上傳的文件
139 FileStream fs = fileInf.OpenRead();
140
141 //把上傳的文件寫入流
142 Stream strm = reqFTP.GetRequestStream();
143
144 //每次讀文件流的KB
145 contentLen = fs.Read(buff, 0, buffLength);
146
147 //流內容沒有結束
148 while (contentLen != 0)
149 {
150 //把內容從FILE STREAM 寫入UPLOAD STREAM
151 strm.Write(buff, 0, contentLen);
152 contentLen = fs.Read(buff, 0, buffLength);
153 }
154
155 //關閉兩個流
156 strm.Close();
157
158 fs.Close();
159
160 retValue = true;
161 }
162 catch (Exception ex)
163 {
164 retValue = false;
165 MessageBox.Show(ex.Message, "Upload Error");
166 }
167
168 return retValue;
169 }
170 public bool CheckFileNameExists(string filePath, string fileName, out string errorinfo)
171 {
172 bool retValue = false;
173 try
174 {
175 String onlyFileName = Path.GetFileName(fileName);
176
177 string newFileName = filePath + "\" + onlyFileName;
178
179 if (File.Exists(newFileName))
180 {
181 errorinfo = string.Format("本地文件{0}已存在,", newFileName);
182 return true;
183 }
184 else
185 errorinfo = "";
186 }
187 catch (Exception ex)
188 {
189 retValue = false;
190 errorinfo = string.Format("因{0},无法下载uc1", ex.Message);
191 }
192 return retValue;
193 }
194 //下面的代碼實現了從FTP服務器下載文件的功u-32515 能
195 public bool Download(string filePath, string fileName, out string errorinfo)
196 {
197 bool retValue = false;
198
199 try
200 {
201 String onlyFileName = Path.GetFileName(fileName);
202
203 string newFileName = filePath + "\" + onlyFileName;
204
205 //if (File.Exists(newFileName))
206 //{
207 // errorinfo = string.Format("本地文件{0}已存在,無法下載", newFileName);
208 // return false;
209 //}
210
211 string url = "ftp://" + ftpServerIP + "/" + fileName;
212 //連接
213 Connect(url);
214
215 reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
216 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
217 Stream ftpStream = response.GetResponseStream();
218 long cl = response.ContentLength;
219 int bufferSize = 2048;
220 int readCount;
221 byte[] buffer = new byte[bufferSize];
222 readCount = ftpStream.Read(buffer, 0, bufferSize);
223
224 FileStream outputStream = new FileStream(newFileName, FileMode.Create);
225 while (readCount > 0)
226 {
227 outputStream.Write(buffer, 0, readCount);
228 readCount = ftpStream.Read(buffer, 0, bufferSize);
229 }
230
231 ftpStream.Close();
232 outputStream.Close();
233 response.Close();
234
235 errorinfo = "";
236
237 retValue = true;
238 }
239 catch (Exception ex)
240 {
241 retValue = false;
242 errorinfo = string.Format("因{0},无法下载uc1", ex.Message);
243 }
244
245 return retValue;
246 }
247
248 //刪除文件
249 public void DeleteFileName(string fileName)
250 {
251 try
252 {
253 FileInfo fileInf = new FileInfo(fileName);
254
255 string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
256
257 //連接
258 Connect(uri);
259
260 //默認為TRUE,連接不會被關閉
261 //在一個命令之後被執行
262 reqFTP.KeepAlive = false;
263
264 //執行執行什麼命令
265 reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
266
267 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
268 response.Close();
269 }
270 catch (Exception ex)
271 {
272 MessageBox.Show(ex.Message, "刪除錯誤");
273 }
274 }
275
276 //創建目錄
277 public bool MakeDir(string dirName)
278 {
279 bool retValue = false;
280
281 try
282 {
283 if (!DirectoryExist(dirName))
284 {
285 string uri = "ftp://" + ftpServerIP + "/" + dirName;
286 //連接
287 Connect(uri);
288
289 reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
290
291 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
292
293 response.Close();
294 }
295
296 retValue = true;
297 }
298 catch (Exception ex)
299 {
300 retValue = false;
301 MessageBox.Show(ex.Message);
302 }
303
304 return retValue;
305 }
306
307 //刪除目錄
308 public void delDir(string dirName)
309 {
310 try
311 {
312 string uri = "ftp://" + ftpServerIP + "/" + dirName;
313 //連接
314 Connect(uri);
315
316 reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory;
317
318 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
319
320 response.Close();
321 }
322 catch (Exception ex)
323 {
324 MessageBox.Show(ex.Message);
325 }
326 }
327
328 //獲得文件大小
329 public long GetFileSize(string filename)
330 {
331 long fileSize = 0;
332
333 try
334 {
335 FileInfo fileInf = new FileInfo(filename);
336
337 string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
338
339 //連接
340 Connect(uri);
341
342 reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
343
344 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
345
346 fileSize = response.ContentLength;
347
348 response.Close();
349 }
350 catch (Exception ex)
351 {
352 MessageBox.Show(ex.Message);
353 }
354 return fileSize;
355 }
356
357 //文件改名
358 public void Rename(string currentFilename, string newFilename)
359 {
360 try
361 {
362 FileInfo fileInf = new FileInfo(currentFilename);
363
364 string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
365 //連接
366 Connect(uri);
367
368 reqFTP.Method = WebRequestMethods.Ftp.Rename;
369
370 reqFTP.RenameTo = newFilename;
371
372 FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
373
374 //Stream ftpStream = response.GetResponseStream();
375
376 //ftpStream.Close();
377
378 response.Close();
379
380 }
381 catch (Exception ex)
382 {
383 MessageBox.Show(ex.Message);
384 }
385 }
386
387 //下面的代碼示例了如何從FTP服務器上獲得文件列表
388 public string[] GetFileList(string path)
389 {
390 return GetFileList("ftp://" + ftpServerIP + "/" + path, WebRequestMethods.Ftp.ListDirectory);
391 }
392
393 //下面的代碼示例了如何從FTP服務器上獲得文件列表
394 public string[] GetFileList()
395 {
396 return GetFileList("ftp://" + ftpServerIP + "/", WebRequestMethods.Ftp.ListDirectory);
397 }
398
399 //獲得文件明細
400 public string[] GetFilesDetailList()
401 {
402 return GetFileList("ftp://" + ftpServerIP + "/", WebRequestMethods.Ftp.ListDirectoryDetails);
403 }
404
405 //獲得文件明細
406 public string[] GetFilesDetailList(string path)
407 {
408 return GetFileList("ftp://" + ftpServerIP + "/" + path, WebRequestMethods.Ftp.ListDirectoryDetails);
409 }
410
411 #region "獲取目錄文件信息"
412 /// <summary>
413 /// 列出FTP服务u22120 器上面当u21069 前目录u30340 的所有文件和目录par /// </summary>
414 public FileStruct[] ListFilesAndDirectories(string path)
415 {
416 Connect(path);
417 reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
418
419 FtpWebResponse Response = null;
420 Response = (FtpWebResponse)reqFTP.GetResponse();
421
422 //Response = Open(this.Uri, WebRequestMethods.Ftp.ListDirectoryDetails);
423 StreamReader stream = new StreamReader(Response.GetResponseStream(), Encoding.Default);
424 string Datastring = stream.ReadToEnd();
425 FileStruct[] list = GetList(Datastring);
426 return list;
427 }
428 /// <summary>
429 /// 獲取FTP服務器上面當前目錄的所有文件
430 /// </summary>
431 public FileStruct[] ListFiles()
432 {
433 FileStruct[] listAll = ListFilesAndDirectories("ftp://" + ftpServerIP + "/");
434 List<FileStruct> listFile = new List<FileStruct>();
435 foreach (FileStruct file in listAll)
436 {
437 if (!file.IsDirectory)
438 {
439 listFile.Add(file);
440 }
441 }
442 return listFile.ToArray();
443 }
444
445 /// <summary>
446 /// 獲取FTP服務器上面當前目錄的所有目錄
447 /// </summary>
448 public FileStruct[] ListDirectories()
449 {
450 FileStruct[] listAll = ListFilesAndDirectories("ftp://" + ftpServerIP + "/");
451 List<FileStruct> listDirectory = new List<FileStruct>();
452 foreach (FileStruct file in listAll)
453 {
454 if (file.IsDirectory)
455 {
456 listDirectory.Add(file);
457 }
458 }
459 return listDirectory.ToArray();
460 }
461
462 /// <summary>
463 /// 獲取文件和目錄列表
464 /// </summary>
465 /// <param name="datastring">FTP返回的列表字符信息</param>
466 private FileStruct[] GetList(string datastring)
467 {
468 List<FileStruct> myListArray = new List<FileStruct>();
469 string[] dataRecords = datastring.Split('
');
470 FileListStyle _directoryListStyle = GuessFileListStyle(dataRecords);
471 foreach (string s in dataRecords)
472 {
473 if (_directoryListStyle != FileListStyle.Unknown && s != "")
474 {
475 FileStruct f = new FileStruct();
476 f.Name = "..";
477 switch (_directoryListStyle)
478 {
479 case FileListStyle.UnixStyle:
480 f = ParseFileStructFromUnixStyleRecord(s);
481 break;
482 case FileListStyle.WindowsStyle:
483 f = ParseFileStructFromWindowsStyleRecord(s);
484 break;
485 }
486 if (!(f.Name == "." || f.Name == ".."))
487 {
488 myListArray.Add(f);
489 }
490 }
491 }
492 return myListArray.ToArray();
493 }
494
495 /// <summary>
496 /// 從Windows格式中返回文件信息
497 /// </summary>
498 /// <param name="Record">文件信息</param>
499 private FileStruct ParseFileStructFromWindowsStyleRecord(string Record)
500 {
501 FileStruct f = new FileStruct();
502 string processstr = Record.Trim();
503 string dateStr = processstr.Substring(0, 8);
504 processstr = (processstr.Substring(8, processstr.Length - 8)).Trim();
505 string timeStr = processstr.Substring(0, 7);
506 processstr = (processstr.Substring(7, processstr.Length - 7)).Trim();
507 DateTimeFormatInfo myDTFI = new CultureInfo("en-US", false).DateTimeFormat;
508 myDTFI.ShortTimePattern = "t";
509 f.CreateTime = DateTime.Parse(dateStr + " " + timeStr, myDTFI);
510 if (processstr.Substring(0, 5) == "<DIR>")
511 {
512 f.IsDirectory = true;
513 processstr = (processstr.Substring(5, processstr.Length - 5)).Trim();
514 }
515 else
516 {
517 string[] strs = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // true);
518 processstr = strs[1];
519 f.IsDirectory = false;
520 }
521 f.Name = processstr;
522 return f;
523 }
524 /// <summary>
525 /// 判斷文件列表的方式Window方式還是Unix方式
526 /// </summary>
527 /// <param name="recordList">文件信息列表</param>
528 private FileListStyle GuessFileListStyle(string[] recordList)
529 {
530 foreach (string s in recordList)
531 {
532 if (s.Length > 10 && Regex.IsMatch(s.Substring(0, 10), "(-|d)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)(-|r)(-|w)(-|x)"))
533 {
534 return FileListStyle.UnixStyle;
535 }
536 else if (s.Length > 8 && Regex.IsMatch(s.Substring(0, 8), "[0-9][0-9]-[0-9][0-9]-[0-9][0-9]"))
537 {
538 return FileListStyle.WindowsStyle;
539 }
540 }
541 return FileListStyle.Unknown;
542 }
543
544 /// <summary>
545 /// 從Unix格式中返回文件信息
546 /// </summary>
547 /// <param name="Record">文件信息</param>
548 private FileStruct ParseFileStructFromUnixStyleRecord(string Record)
549 {
550 FileStruct f = new FileStruct();
551 string processstr = Record.Trim();
552 f.Flags = processstr.Substring(0, 10);
553 f.IsDirectory = (f.Flags[0] == 'd');
554 processstr = (processstr.Substring(11)).Trim();
555 _cutSubstringFromStringWithTrim(ref processstr, ' ', 0); //跳過一部分
556 f.Owner = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
557 f.Group = _cutSubstringFromStringWithTrim(ref processstr, ' ', 0);
558 _cutSubstringFromStringWithTrim(ref processstr, ' ', 0); //跳過一部分
559 string yearOrTime = processstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[2];
560 if (yearOrTime.IndexOf(":") >= 0) //time
561 {
562 processstr = processstr.Replace(yearOrTime, DateTime.Now.Year.ToString());
563 }
564 f.CreateTime = DateTime.Parse(_cutSubstringFromStringWithTrim(ref processstr, ' ', 8));
565 f.Name = processstr; //最後就是名稱
566 return f;
567 }
568
569 /// <summary>
570 /// 按照一定的規則進行字符串截取
571 /// </summary>
572 /// <param name="s">截取的字符串</param>
573 /// <param name="c">查找的字符</param>
574 /// <param name="startIndex">查找的位置</param>
575 private string _cutSubstringFromStringWithTrim(ref string s, char c, int startIndex)
576 {
577 int pos1 = s.IndexOf(c, startIndex);
578 string retString = s.Substring(0, pos1);
579 s = (s.Substring(pos1)).Trim();
580 return retString;
581 }
582
583 #endregion
584
585 #region "判斷目錄或文件是否存在"
586 /// <summary>
587 /// 判斷當前目錄下指定的子目錄是否存在
588 /// </summary>
589 /// <param name="RemoteDirectoryName">指定的目錄名</param>
590 public bool DirectoryExist(string RemoteDirectoryName)
591 {
592 try
593 {
594 if (!IsValidPathChars(RemoteDirectoryName))
595 {
596 throw new Exception("目錄名含有無法解析的字符,請確認!");
597 }
598
599 FileStruct[] listDir = ListDirectories();
600 foreach (FileStruct dir in listDir)
601 {
602 if (dir.Name == RemoteDirectoryName)
603 {
604 return true;
605 }
606 }
607
608 return false;
609 }
610 catch (Exception ex)
611 {
612 throw ex;
613 }
614 }
615 /// <summary>
616 /// 判斷一個遠程文件是否存在服務器當前目錄下面
617 /// </summary>
618 /// <param name="RemoteFileName">遠程文件名</param>
619 public bool FileExist(string RemoteFileName)
620 {
621 try
622 {
623 if (!IsValidFileChars(RemoteFileName))
624 {
625 throw new Exception("文件名含有無法解析的字符,請確認!");
626 }
627 FileStruct[] listFile = ListFiles();
628 foreach (FileStruct file in listFile)
629 {
630 if (file.Name == RemoteFileName)
631 {
632 return true;
633 }
634 }
635 return false;
636 }
637 catch (Exception ex)
638 {
639 throw ex;
640 }
641 }
642 #endregion
643
644 #region "文件,目錄名稱有效性判斷"
645 /// <summary>
646 /// 判斷目錄名中字符是否合法
647 /// </summary>
648 /// <param name="DirectoryName">目錄名稱</param>
649 public bool IsValidPathChars(string DirectoryName)
650 {
651 char[] invalidPathChars = Path.GetInvalidPathChars();
652 char[] DirChar = DirectoryName.ToCharArray();
653 foreach (char C in DirChar)
654 {
655 if (Array.BinarySearch(invalidPathChars, C) >= 0)
656 {
657 return false;
658 }
659 }
660 return true;
661 }
662 /// <summary>
663 /// 判斷文件名中字符是否合法
664 /// </summary>
665 /// <param name="FileName">文件名稱</param>
666 public bool IsValidFileChars(string FileName)
667 {
668 char[] invalidFileChars = Path.GetInvalidFileNameChars();
669 char[] NameChar = FileName.ToCharArray();
670 foreach (char C in NameChar)
671 {
672 if (Array.BinarySearch(invalidFileChars, C) >= 0)
673 {
674 return false;
675 }
676 }
677 return true;
678 }
679 #endregion
680
681 #region "註釋"
682 /*
683 #region 删除文件
684 /// <summary>
685 /// 从TP服务u22120 器上面删u-27036 除一个u25991 文件
686 /// </summary>
687 /// <param name="RemoteFileName">远uc2程文件名</param>
688 public void DeleteFile(string RemoteFileName)
689 {
690 try
691 {
692 if (!IsValidFileChars(RemoteFileName))
693 {
694 throw new Exception("文件名非法!");
695 }
696 Response = Open(new Uri(this.Uri.ToString() + RemoteFileName), WebRequestMethods.Ftp.DeleteFile);
697 }
698 catch (Exception ep)
699 {
700 ErrorMsg = ep.ToString();
701 throw ep;
702 }
703 }
704 #endregion
705
706 #region 重命名文件
707 /// <summary>
708 /// 更改一个u25991 文件的名称u25110 或一个u30446 目录u30340 的名称par /// </summary>
709 /// <param name="RemoteFileName">原始文件或目录u21517 名称uc1</param>
710 /// <param name="NewFileName">新的文件或目录u30340 的名称uc1</param>
711 public bool ReName(string RemoteFileName, string NewFileName)
712 {
713 try
714 {
715 if (!IsValidFileChars(RemoteFileName) || !IsValidFileChars(NewFileName))
716 {
717 throw new Exception("文件名非法!");
718 }
719 if (RemoteFileName == NewFileName)
720 {
721 return true;
722 }
723 if (FileExist(RemoteFileName))
724 {
725 Request = OpenRequest(new Uri(this.Uri.ToString() + RemoteFileName), WebRequestMethods.Ftp.Rename);
726 Request.RenameTo = NewFileName;
727 Response = (FtpWebResponse)Request.GetResponse();
728
729 }
730 else
731 {
732 throw new Exception("文件在服务u22120 器上不存在!");
733 }
734 return true;
735 }
736 catch (Exception ep)
737 {
738 ErrorMsg = ep.ToString();
739 throw ep;
740 }
741 }
742 #endregion
743
744 #region 拷贝u12289 、移动u25991 文件
745 /// <summary>
746 /// 把当u21069 前目录u19979 下面的一个u25991 文件拷贝u21040 到服务u22120 器上面另外的目录u20013 中,注意,拷贝u25991 文件之后,当u21069 前工作目录u-28712 ?是文件原来u25152 所在的目录par /// </summary>
747 /// <param name="RemoteFile">当uc2前目录u19979 下的文件名</param>
748 /// <param name="DirectoryName">新目录u21517 名称u12290 。
749 /// 说uc2明:如果新目录u26159 是当u21069 前目录u30340 的子目录u-244 ,则u30452 直接指定子目录u12290 。如: SubDirectory1/SubDirectory2 ;
750 /// 如果新目录u19981 不是当u21069 前目录u30340 的子目录u-244 ,则u24517 必须u20174 ?根目录u19968 一级u19968 一级u30340 的指定。如:./NewDirectory/SubDirectory1/SubDirectory2
751 /// </param>
752 /// <returns></returns>
753 public bool CopyFileToAnotherDirectory(string RemoteFile, string DirectoryName)
754 {
755 string CurrentWorkDir = this.DirectoryPath;
756 try
757 {
758 byte[] bt = DownloadFile(RemoteFile);
759 GotoDirectory(DirectoryName);
760 bool Success = UploadFile(bt, RemoteFile, false);
761 this.DirectoryPath = CurrentWorkDir;
762 return Success;
763 }
764 catch (Exception ep)
765 {
766 this.DirectoryPath = CurrentWorkDir;
767 ErrorMsg = ep.ToString();
768 throw ep;
769 }
770 }
771 /// <summary>
772 /// 把当u21069 前目录u19979 下面的一个u25991 文件移动u21040 到服务u22120 器上面另外的目录u20013 中,注意,移动u25991 文件之后,当u21069 前工作目录u-28712 ?是文件原来u25152 所在的目录par /// </summary>
773 /// <param name="RemoteFile">当uc2前目录u19979 下的文件名</param>
774 /// <param name="DirectoryName">新目录u21517 名称u12290 。
775 /// 说uc2明:如果新目录u26159 是当u21069 前目录u30340 的子目录u-244 ,则u30452 直接指定子目录u12290 。如: SubDirectory1/SubDirectory2 ;
776 /// 如果新目录u19981 不是当u21069 前目录u30340 的子目录u-244 ,则u24517 必须u20174 ?根目录u19968 一级u19968 一级u30340 的指定。如:./NewDirectory/SubDirectory1/SubDirectory2
777 /// </param>
778 /// <returns></returns>
779 public bool MoveFileToAnotherDirectory(string RemoteFile, string DirectoryName)
780 {
781 string CurrentWorkDir = this.DirectoryPath;
782 try
783 {
784 if (DirectoryName == "")
785 return false;
786 if (!DirectoryName.StartsWith("/"))
787 DirectoryName = "/" + DirectoryName;
788 if (!DirectoryName.EndsWith("/"))
789 DirectoryName += "/";
790 bool Success = ReName(RemoteFile, DirectoryName + RemoteFile);
791 this.DirectoryPath = CurrentWorkDir;
792 return Success;
793 }
794 catch (Exception ep)
795 {
796 this.DirectoryPath = CurrentWorkDir;
797 ErrorMsg = ep.ToString();
798 throw ep;
799 }
800 }
801 #endregion
802
803 #region 建立、删u-27036 除子目录par /// <summary>
804 /// 在FTP服务u22120 器上当u21069 前工作目录u24314 建立一个u23376 子目录par /// </summary>
805 /// <param name="DirectoryName">子目录u21517 名称uc1</param>
806 public bool MakeDirectory(string DirectoryName)
807 {
808 try
809 {
810 if (!IsValidPathChars(DirectoryName))
811 {
812 throw new Exception("目录u21517 名非法!");
813 }
814 if (DirectoryExist(DirectoryName))
815 {
816 throw new Exception("服务u22120 器上面已经u23384 存在同名的文件名或目录u21517 名!");
817 }
818 Response = Open(new Uri(this.Uri.ToString() + DirectoryName), WebRequestMethods.Ftp.MakeDirectory);
819 return true;
820 }
821 catch (Exception ep)
822 {
823 ErrorMsg = ep.ToString();
824 throw ep;
825 }
826 }
827 /// <summary>
828 /// 从当前工作目录u20013 中删u-27036 除一个u23376 子目录par /// </summary>
829 /// <param name="DirectoryName">子目录u21517 名称uc1</param>
830 public bool RemoveDirectory(string DirectoryName)
831 {
832 try
833 {
834 if (!IsValidPathChars(DirectoryName))
835 {
836 throw new Exception("目录u21517 名非法!");
837 }
838 if (!DirectoryExist(DirectoryName))
839 {
840 throw new Exception("服务u22120 器上面不存在指定的文件名或目录u21517 名!");
841 }
842 Response = Open(new Uri(this.Uri.ToString() + DirectoryName), WebRequestMethods.Ftp.RemoveDirectory);
843 return true;
844 }
845 catch (Exception ep)
846 {
847 ErrorMsg = ep.ToString();
848 throw ep;
849 }
850 }
851 #endregion
852
853 #region 目录u20999 切换u25805 操作
854 /// <summary>
855 /// 进uc2入一个u30446 目录par /// </summary>
856 /// <param name="DirectoryName">
857 /// 新目录u30340 的名字。
858 /// 说明:如果新目录u26159 是当u21069 前目录u30340 的子目录u-244 ,则u30452 直接指定子目录u12290 。如: SubDirectory1/SubDirectory2 ;
859 /// 如果新目录u19981 不是当u21069 前目录u30340 的子目录u-244 ,则u24517 必须u20174 ?根目录u19968 一级u19968 一级u30340 的指定。如:./NewDirectory/SubDirectory1/SubDirectory2
860 /// </param>
861 public bool GotoDirectory(string DirectoryName)
862 {
863 string CurrentWorkPath = this.DirectoryPath;
864 try
865 {
866 DirectoryName = DirectoryName.Replace("\", "/");
867 string[] DirectoryNames = DirectoryName.Split(new char[] { '/' });
868 if (DirectoryNames[0] == ".")
869 {
870 this.DirectoryPath = "/";
871 if (DirectoryNames.Length == 1)
872 {
873 return true;
874 }
875 Array.Clear(DirectoryNames, 0, 1);
876 }
877 bool Success = false;
878 foreach (string dir in DirectoryNames)
879 {
880 if (dir != null)
881 {
882 Success = EnterOneSubDirectory(dir);
883 if (!Success)
884 {
885 this.DirectoryPath = CurrentWorkPath;
886 return false;
887 }
888 }
889 }
890 return Success;
891
892 }
893 catch (Exception ep)
894 {
895 this.DirectoryPath = CurrentWorkPath;
896 ErrorMsg = ep.ToString();
897 throw ep;
898 }
899 }
900
901 /// <summary>
902 /// 从当前工作目录u-28709 ?入一个u23376 子目录par /// </summary>
903 /// <param name="DirectoryName">子目录u21517 名称uc1</param>
904 private bool EnterOneSubDirectory(string DirectoryName)
905 {
906 try
907 {
908 if (DirectoryName.IndexOf("/") >= 0 || !IsValidPathChars(DirectoryName))
909 {
910 throw new Exception("目录u21517 名非法!");
911 }
912 if (DirectoryName.Length > 0 && DirectoryExist(DirectoryName))
913 {
914 if (!DirectoryName.EndsWith("/"))
915 {
916 DirectoryName += "/";
917 }
918 _DirectoryPath += DirectoryName;
919 return true;
920 }
921 else
922 {
923 return false;
924 }
925 }
926 catch (Exception ep)
927 {
928 ErrorMsg = ep.ToString();
929 throw ep;
930 }
931 }
932
933 /// <summary>
934 /// 从当前工作目录u24448 往上一级u30446 目录par /// </summary>
935 public bool ComeoutDirectory()
936 {
937 if (_DirectoryPath == "/")
938 {
939 ErrorMsg = "当uc2前目录u24050 已经u26159 是根目录u-255 !";
940 throw new Exception("当前目录u24050 已经u26159 是根目录u-255 !");
941 }
942 char[] sp = new char[1] { '/' };
943
944 string[] strDir = _DirectoryPath.Split(sp, StringSplitOptions.RemoveEmptyEntries);
945 if (strDir.Length == 1)
946 {
947 _DirectoryPath = "/";
948 }
949 else
950 {
951 _DirectoryPath = String.Join("/", strDir, 0, strDir.Length - 1);
952 }
953 return true;
954
955 }
956 #endregion
957 */
958 #endregion
959 }
960 }

浙公网安备 33010602011771号