2011-08-15 14 views
19

WebRequestMethods.Ftp.ListDirectoryDetails FTP yanıtı ayrıştırmak ve WebRequestMethods.Ftp.ListDirectoryDetails kullanarak FtpWebRequest tepki dönen yanıtı ayrıştırmak için yeteneği gerektiren yöntemi. Tüm yanıtlar aynı formatta takip edilirse oldukça kolay olurdu, ancak farklı FTP sunucu yazılımı farklı yanıt formatları sağlıyor.C# sınıfı yeni güncellemeler için FTP lokasyonlarını takip etmek için bir hizmet yaratıyorum

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 

Ve başka sunucu döndürebilir:

Örneğin biri döndürebilir

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 

Ve ince farkları Ben arabada bir dizi olma olasılığı yani başka farklılıklar da gözlenmiştir Henüz karşılaşmadım.

Bu durumları sorunsuzca işleyen tam olarak yönetilen (Windows'ta harici dll'ye erişim gerektirmez) C# sınıfı bilen var mı?

Yalnızca bir dizinin içeriğini aşağıdaki ayrıntılarla birlikte listelemem gerekiyor: Dosya/dizin adı, son güncelleme veya zaman damgası, dosya/dizin adı. Herhangi Önerileriniz için şimdiden

sayesinde Gavin

+2

Sadece bir not - FTP, girişin tam biçimini belirtmiyor ve 400'den fazla biçim var (listelediğiniz yalnızca iki, Windows ve Unix olsa da). –

+1

Phew - bu bir çok format! – Gavin

+1

Bu örneği buldum, ancak çok sağlam olduğundan şüphe duyuyorum - http://blogs.msdn.com/b/adarshk/archive/2004/09/15/230177.aspx – Gavin

cevap

4

bir çözüm ben rastladım EdtFTPnet

edtftpnet yüzden ideal olan, farklı bir FTP Birçok seçenek kolları uzunca bir özellik dolu bir çözüm gibi görünüyor olduğunu.

Bu, http://www.ftp2rss.com için ne kadar çalıştığım ücretsiz açık kaynak çözümdür (kendime ihtiyacım olan ancak başkalarına da faydalı olabileceğimi düşündüğüm küçük bir araç).

0

Ftp.dll FTP client'a bakın.

Windows, Unix ve Netware platformlarındaki çoğu FTP sunucusu için automatic directory listing parser içerir.

Lütfen bunun geliştirdiğim ticari bir ürün olduğunu unutmayın.

+0

Şerefe Pawel, çok beğeni topladı. Ücretsiz sürümü ile bazı sınırlarla karşılaşmadığı sürece şimdilik ücretsiz EdtFTPnet sürümüne sadık kalacaktır. – Gavin

4

Bu aynı sorunu karşı karşıyayım ve yakalama grupları kullanarak her satırından ilgili bilgileri ayrıştırmak için Regex kullanarak bir (çok sağlam değil olsa) basit bir çözüm oluşturduk:

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

Daha sonra ayıklamak tarafından yakalama gruplarının dışında değerler:

 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; 

Bazı şeyler not değildir:

  • , yalnızca yukarıdaki ftpResponse değişkeninde bulunan biçimiyle dizin yanıtları için çalışır. Benim durumumda, her defasında aynı FTP sunucusuna erişme şansım olduğu için yanıt formatının değişmesi olası değildir.
  • yearTime değişkeni, dosyanın zaman damgasının yılını veya saatini EITHER temsil edebilir.yapacak bu kodu listeleme bu yakalama grubu bir saat yerine ilk (DOS/Windows) için yıl
+0

Harika çalışıyor! –

6

içerdiğini gösterir karakteri: Sen kolon örneğine bakarak elle ayrıştırmak gerekir :

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

Sen alacak:

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 

diğer (* nix) listesi için my answer to Parsing FtpWebRequest ListDirectoryDetails line bakın.


Ama aslında ListDirectoryDetails tarafından döndürülen liste ayrıştırmak çalışırken gitmek için doğru yol değildir.

RFC 3659 numaralı belgede belirtilen makine tarafından okunabilir bir biçimde bir dizin listesi döndüren modern MLSD komutunu destekleyen bir FTP istemcisi kullanmak istiyorsunuz. Eski LIST komutunun (FtpWebRequest tarafından ListDirectoryDetails yöntemi için dahili olarak kullanılan) döndürülen insan tarafından okunabilir biçimini ayrıştırma, eski FTP sunucuları ile konuşurken, MLSD komutunu desteklemeyen son çare seçeneği olarak kullanılmalıdır. IIS FTP sunucusu).


WinSCP .NET assembly ile Örneğin, onun Session.ListDirectory veya Session.EnumerateRemoteFiles yöntemleri kullanabilirsiniz.

MLSD komutunu dahili olarak kullanıyorlar, ancak LIST komutuna geri dönebilir ve düzinelerce farklı insan tarafından okunabilir listeleme biçimlerini destekleyebilirler.

  • Name
  • LastWriteTime (doğru saat dilimiyle)
  • Length
  • FilePermissions (bireysel haklar ayrıştırılır)
  • :

    döndü listeleme gibi özellikleri olan RemoteFileInfo instances toplanması olarak sunulur Group

  • IsThisDirectoryIsDirectory
  • IsParentDirectory
  • Owner

  • Diğer birçok 3. parti kütüphaneler aynısını yapacak (Ben WinSCP yazarı değilim). FtpWebRequest class'u kullanmak bu amaç için güvenilir değildir. Ne yazık ki, .NET çerçevesinde başka bir yerleşik FTP istemcisi yok.

    +0

    Paylaştığınız için teşekkürler. Bunu sorabilir miyim - WinSCP'de nasıl yaparsınız? – c00000fd

    +0

    @ c00000fd Ne yapar? Liste dizini? Https://winscp.net/eng/docs/library_session_listdirectory#example adresine bakın. –

    İlgili konular