2011-08-15 24 views
19

tôi là tạo ra một dịch vụ để giám sát các địa điểm FTP để cập nhật mới và đòi hỏi khả năng phân tích các phản ứng trở về từ một phản ứng FtpWebRequest sử dụng WebRequestMethods.Ftp.ListDirectoryDetails. Nó sẽ là khá dễ dàng nếu tất cả các phản ứng theo định dạng tương tự, nhưng phần mềm máy chủ FTP khác nhau cung cấp các định dạng phản ứng khác nhau.C# lớp để phân tích phản ứng WebRequestMethods.Ftp.ListDirectoryDetails FTP

Ví dụ người ta có thể quay trở lại:

08-10-11 12:02PM  <DIR>   Version2 
06-25-09 02:41PM   144700153 image34.gif 
06-25-09 02:51PM   144700153 updates.txt 
11-04-10 02:45PM   144700214 digger.tif 

Và máy chủ khác có thể quay trở lại:

d--x--x--x 2 ftp  ftp   4096 Mar 07 2002 bin 
-rw-r--r-- 1 ftp  ftp  659450 Jun 15 05:07 TEST.TXT 
-rw-r--r-- 1 ftp  ftp  101786380 Sep 08 2008 TEST03-05.TXT 
drwxrwxr-x 2 ftp  ftp   4096 May 06 12:24 dropoff 

Và sự khác biệt khác đã được quan sát cũng vì vậy có khả năng là một số khác biệt tinh tế tôi thiên đường' t gặp chưa.

Có ai biết được quản lý hoàn toàn (không yêu cầu quyền truy cập vào dll bên ngoài trên Windows) C# lớp xử lý các tình huống này liền mạch không?

Tôi chỉ cần liệt kê nội dung của thư mục với các chi tiết sau: Tên tệp/thư mục, dấu thời gian được tạo hoặc cập nhật lần cuối, tên tệp/thư mục.

Cảm ơn trước cho bất cứ đề nghị, Gavin

+2

Chỉ cần lưu ý - FTP không chỉ định định dạng chính xác của danh sách và tồn tại trên 400 định dạng (mặc dù chỉ có hai định dạng bạn đã liệt kê, Windows và Unix) được sử dụng nhiều nhất. –

+1

Phew - đó là rất nhiều định dạng! – Gavin

+1

Tôi tìm thấy ví dụ này, nhưng tôi nghi ngờ nó quá mạnh mẽ - http://blogs.msdn.com/b/adarshk/archive/2004/09/15/230177.aspx – Gavin

Trả lời

4

Một giải pháp tôi đi qua là EdtFTPnet

EdtFTPnet có vẻ là một giải pháp khá tính năng đóng gói để xử lý nhiều lựa chọn FTP khác nhau như vậy là lý tưởng.

Đó là giải pháp mã nguồn mở miễn phí mà tôi đã sử dụng cho http://www.ftp2rss.com (một công cụ nhỏ mà tôi cần bản thân mình nhưng cũng có thể hữu ích với những người khác).

0

Hãy xem Ftp.dll FTP client.

Nó bao gồm automatic directory listing parser cho hầu hết các máy chủ FTP trên nền tảng Windows, Unix và Netware.

Xin lưu ý rằng đây là sản phẩm thương mại mà tôi đã phát triển.

+0

Chúc mừng Pawel, được nhiều người đánh giá cao. Sẽ dính vào phiên bản EdtFTPnet miễn phí ngay bây giờ trừ khi tôi gặp phải một số giới hạn với phiên bản miễn phí của nó. – Gavin

4

Tôi đang phải đối mặt với vấn đề này giống nhau và tôi đã xây dựng một giải pháp đơn giản (mặc dù không phải là rất mạnh mẽ) sử dụng một Regex để phân tích các thông tin có liên quan từ mỗi dòng sử dụng các nhóm chụp:

public static Regex FtpListDirectoryDetailsRegex = new Regex(@".*(?<month>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\s*(?<day>[0-9]*)\s*(?<yearTime>([0-9]|:)*)\s*(?<fileName>.*)", RegexOptions.Compiled | RegexOptions.IgnoreCase); 

Sau đó bạn có thể trích xuất các giá trị ra khỏi nhóm chụp bởi:

 string ftpResponse = "-r--r--r-- 1 ftp ftp    0 Nov 19 11:08 aaa.txt"; 
     Match match = FtpListDirectoryDetailsRegex.Match(ftpResponse); 
     string month = match.Groups["month"].Value; 
     string day = match.Groups["day"].Value; 
     string yearTime = match.Groups["yearTime"].Value; 
     string fileName = match.Groups["fileName"].Value; 

Một số điều không lưu ý là:

  • điều này sẽ chỉ hoạt động đối với các thư trả lời thư mục với định dạng được mô tả trong biến số ftpResponse ở trên. Trong trường hợp của tôi, tôi may mắn khi chỉ truy cập vào cùng một máy chủ FTP mỗi lần và do đó không chắc rằng định dạng phản hồi sẽ thay đổi.
  • biến số yearTime có thể đại diện cho EITHER năm hoặc thời gian của dấu thời gian của tệp.Bạn sẽ cần phân tích cú pháp thủ công này bằng cách tìm kiếm phiên bản của dấu hai chấm: ký tự cho biết nhóm chụp này chứa thời gian thay vì năm
+0

Nó hoạt động tuyệt vời! –

6

Lần đầu tiên (DOS/Windows) liệt kê mã này sẽ làm :

FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/"); 
request.Credentials = new NetworkCredential("user", "password"); 
request.Method = WebRequestMethods.Ftp.ListDirectoryDetails; 
StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()); 

string pattern = @"^(\d+-\d+-\d+\s+\d+:\d+(?:AM|PM))\s+(<DIR>|\d+)\s+(.+)$"; 
Regex regex = new Regex(pattern); 
IFormatProvider culture = CultureInfo.GetCultureInfo("en-us"); 
while (!reader.EndOfStream) 
{ 
    string line = reader.ReadLine(); 
    Match match = regex.Match(line); 
    DateTime modified = 
     DateTime.ParseExact(
      match.Groups[1].Value, "MM-dd-yy hh:mmtt", culture, DateTimeStyles.None); 
    long size = (match.Groups[2].Value != "<DIR>") ? long.Parse(match.Groups[2].Value) : 0; 
    string name = match.Groups[3].Value; 

    Console.WriteLine(
     "{0,-16} size = {1,9} modified = {2}", 
     name, size, modified.ToString("yyyy-MM-dd HH:mm")); 
} 

Bạn sẽ nhận được:

Version2   size =   0 modified = 2011-08-10 12:02 
image34.gif  size = 144700153 modified = 2009-06-25 14:41 
updates.txt  size = 144700153 modified = 2009-06-25 14:51 
digger.tif  size = 144700214 modified = 2010-11-04 14:45 

Đối với (* nix) niêm yết khác, xem my answer to Parsing FtpWebRequest ListDirectoryDetails line.


Nhưng, thực sự cố gắng phân tích cú pháp danh sách được trả về bởi ListDirectoryDetails không phải là cách phù hợp để thực hiện.

Bạn muốn sử dụng ứng dụng khách FTP hỗ trợ lệnh MLSD hiện đại trả về danh sách thư mục ở định dạng có thể đọc được được chỉ định trong RFC 3659. Phân tích cú pháp định dạng con người có thể đọc được trả về bởi lệnh LIST cổ xưa (được sử dụng trong nội bộ theo phương thức FtpWebRequest cho phương thức ListDirectoryDetails) nên được sử dụng làm tùy chọn cuối cùng, khi nói chuyện với máy chủ FTP lỗi thời, không hỗ trợ lệnh MLSD (như Microsoft Máy chủ FTP IIS).


Ví dụ với WinSCP .NET assembly, bạn có thể sử dụng Session.ListDirectory hoặc Session.EnumerateRemoteFiles của phương pháp.

Họ sử dụng nội bộ lệnh MLSD nhưng có thể quay lại lệnh LIST và hỗ trợ hàng tá định dạng danh sách khác nhau có thể đọc được.

Việc niêm yết trở lại được trình bày như bộ sưu tập của RemoteFileInfo instances với những đặc tính như:

  • Name
  • LastWriteTime (với múi giờ đúng)
  • Length
  • FilePermissions (phân tích thành các quyền cá nhân)
  • Group
  • Owner
  • IsDirectory
  • IsParentDirectory
  • IsThisDirectory

(Tôi là tác giả của WinSCP)


Hầu hết các thư viện của bên thứ 3 khác sẽ làm như vậy. Sử dụng FtpWebRequest class không đáng tin cậy cho mục đích này. Thật không may, không có máy khách FTP tích hợp khác trong khuôn khổ .NET.

+0

Cảm ơn bạn đã chia sẻ. Tôi có thể hỏi - làm thế nào để bạn làm điều đó trong WinSCP? – c00000fd

+0

@ c00000fd Làm gì? Danh sách thư mục? Xem https://winscp.net/eng/docs/library_session_listdirectory#example –

Các vấn đề liên quan