2009-08-14 20 views
9

के लिए FileSystemWatcher एफ़टीपी स्थान (सी # में) के लिए FileSystemWatcher को मैं कैसे कार्यान्वित कर सकता हूं। विचार यह है कि जब भी एफ़टीपी स्थान में कुछ भी जोड़ा जाता है, तो मैं इसे अपनी स्थानीय मशीन पर कॉपी करना चाहता हूं। कोई विचार उपयोगी होगा।एफ़टीपी

यह मेरे पिछले प्रश्न Selective FTP download using .NET का अनुवर्ती है।

+0

आप मतदान प्रकार के दृष्टिकोण का उपयोग करने जा रहे हैं। यह जांचने के लिए कि क्या कोई नई फाइल है या नहीं, आपको समय-समय पर एफटीपी साइट की जांच करनी होगी। – jersoft

उत्तर

14

आपको एक मतदान समाधान लागू करना होगा, जहां आप समय-समय पर निर्देशिका सामग्री मांगते रहेंगे। पिछली कॉल से कैश की गई सूची में इसकी तुलना करें और यह निर्धारित करें कि इस तरह क्या हुआ।

एफ़टीपी प्रोटोकॉल में कुछ भी नहीं है जो दुर्भाग्यवश आपकी मदद करेगा।

3

अपने ftp स्थान पर इंगित करने के लिए FileSystemWatcher बनाने के लिए एक सरल सेवा लिखें।

फिर जब कोई फ़ाइल अपलोड या संशोधित की जाती है, तो आपकी सेवा में एक ईवेंट निकाल दिया जाएगा, जिसका उपयोग आप फ़ाइल को अपनी स्थानीय मशीन पर कॉपी करने के लिए कर सकते हैं। मेजबान विंडोज ऑपरेटिंग सिस्टम के साथ घटनाओं के लिए पंजीकरण करके this blog

+0

क्या 'फाइलसिस्टम वाटर' यूआरएल के साथ काम करता है? –

+0

यूएनसी स्थान, यूआरएल नहीं। – Bravax

7

FileSystemWatcher वर्ग काम करता है:
File.Copy आदि

पर एक नज़र हवलदार। इस प्रकार, यह विंडोज सिस्टम पर होस्ट की गई निर्देशिकाओं के लिए स्थानीय पथ और यूएनसी पथ पर काम करने तक ही सीमित है। FileSystemWatcher पर एमएसडीएन दस्तावेज उन पथों को बताता है जिनका आप उपयोग कर सकते हैं और कक्षा का उपयोग करने में संभावित समस्याओं में से कुछ।

यदि आप किसी FTP साइट पर परिवर्तनों के बारे में सतर्क रहना चाहते हैं, तो आपको निगरानी में रुचि रखने वाली फ़ाइलों या फ़ोल्डरों की वर्तमान स्थिति के लिए एक मतदान तंत्र का उपयोग करना होगा। परिवर्तनों के लिए एफ़टीपी साइट के स्नैपशॉट की तुलना करके फ़ाइलों को जोड़े और हटाए जाने पर आप देख पाएंगे और जब आप परिवर्तनों का पता लगाते हैं तो इसी तरह की घटनाओं को उठाते हैं। दुर्भाग्य से आप घटनाओं का नाम बदलने में सक्षम नहीं होंगे, लेकिन इस तरह की निगरानी करने के लिए अन्य परिवर्तन सरल होना चाहिए।

0

जिस तरह से मैं इसे संभालता हूं वह एक तत्व बाइट सरणी अपलोड करना है, जिसका नाम ".ftpComplete" है। FileSystemWatcher केवल ".ftpComplete" फ़ाइलों के लिए देखता है, और अपलोड की गई वास्तविक फ़ाइल को जानने के लिए अंत में स्ट्रिप्स। चूंकि ".ftpComplete" फ़ाइल केवल 1 बाइट है, यह के रूप में तेजी से के बारे में के रूप में यह FTP सर्वर पर बनाई गई है अपलोड करता है, तो एक बार आप जो कुछ भी आप मुख्य अपलोड की गई फ़ाइल

 FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(
      FTPAddress + "/" + Path.GetFileName(filePath) + ".ftpComplete"); 
     request.Method = WebRequestMethods.Ftp.UploadFile; 
     request.Credentials = new NetworkCredential(username, password); 
     request.UsePassive = true; 
     request.UseBinary = true; 
     request.KeepAlive = false; 
     byte[] buffer = new byte[1]; 
     Stream reqStream = request.GetRequestStream(); 
     reqStream.Write(buffer, 0, buffer.Length); 
     reqStream.Close(); 
2

साथ की जरूरत है इसे नष्ट कर दिया जा सकता है आप निम्न विधि द्वारा एफ़टीपी स्थान की निगरानी कर सकते:

public class FtpFileSystemWatcher 
{ 

    public bool IsRunning 
    { 
     get; 
     private set; 
    } 
    public string FtpUserName 
    { 
     get; 
     set; 
    } 
    public string FtpPassword 
    { 
     get; 
     set; 
    } 
    public string FtpLocationToWatch 
    { 
     get; 
     set; 
    } 
    public string DownloadTo 
    { 
     get; 
     set; 
    } 
    public bool KeepOrignal 
    { 
     get; 
     set; 
    } 
    public bool OverwriteExisting 
    { 
     get; 
     set; 
    } 
    public int RecheckIntervalInSeconds 
    { 
     get; 
     set; 
    } 
    private bool DownloadInprogress 
    { 
     get; 
     set; 
    } 

    private System.Timers.Timer JobProcessor; 

    public FtpFileSystemWatcher(string FtpLocationToWatch = "", string DownloadTo = "", int RecheckIntervalInSeconds = 1, string UserName = "", string Password = "", bool KeepOrignal = false, bool OverwriteExisting = false) 
    { 
     this.FtpUserName = UserName; 
     this.FtpPassword = Password; 
     this.FtpLocationToWatch = FtpLocationToWatch; 
     this.DownloadTo = DownloadTo; 
     this.KeepOrignal = KeepOrignal; 
     this.RecheckIntervalInSeconds = RecheckIntervalInSeconds; 
     this.OverwriteExisting = OverwriteExisting; 

     if (this.RecheckIntervalInSeconds < 1) this.RecheckIntervalInSeconds = 1; 
    } 

    public void StartDownloading() 
    { 

     JobProcessor = new Timer(this.RecheckIntervalInSeconds * 1000); 
     JobProcessor.AutoReset = false; 
     JobProcessor.Enabled = false; 
     JobProcessor.Elapsed += (sender, e) => 
     { 
      try 
      { 

       this.IsRunning = true; 

       string[] FilesList = GetFilesList(this.FtpLocationToWatch, this.FtpUserName, this.FtpPassword); 

       if (FilesList == null || FilesList.Length < 1) 
       { 
        return; 
       } 

       foreach (string FileName in FilesList) 
       { 
        if (!string.IsNullOrWhiteSpace(FileName)) 
        { 
         DownloadFile(this.FtpLocationToWatch, this.DownloadTo, FileName.Trim(), this.FtpUserName, this.FtpPassword, this.OverwriteExisting); 

         if (!this.KeepOrignal) 
         { 
          DeleteFile(Path.Combine(this.FtpLocationToWatch, FileName.Trim()), this.FtpUserName, this.FtpPassword); 
         } 
        } 
       } 

       this.IsRunning = false; 
       JobProcessor.Enabled = true;      
      } 

      catch (Exception exp) 
      { 
       this.IsRunning = false; 
       JobProcessor.Enabled = true; 
       Console.WriteLine(exp.Message); 
      } 
     }; 

     JobProcessor.Start(); 
    } 

    public void StopDownloading() 
    { 
     try 
     { 
      this.JobProcessor.Dispose(); 
      this.IsRunning = false; 
     } 
     catch { } 
    } 

    private void DeleteFile(string FtpFilePath, string UserName, string Password) 
    { 
     FtpWebRequest FtpRequest; 
     FtpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(FtpFilePath)); 
     FtpRequest.UseBinary = true; 
     FtpRequest.Method = WebRequestMethods.Ftp.DeleteFile; 

     FtpRequest.Credentials = new NetworkCredential(UserName, Password); 
     FtpWebResponse response = (FtpWebResponse)FtpRequest.GetResponse(); 
     response.Close(); 

    } 
    private void DownloadFile(string FtpLocation, string FileSystemLocation, string FileName, string UserName, string Password, bool OverwriteExisting) 
    { 
     try 
     { 
      const int BufferSize = 2048; 
      byte[] Buffer = new byte[BufferSize]; 

      FtpWebRequest Request; 
      FtpWebResponse Response; 

      if (File.Exists(Path.Combine(FileSystemLocation, FileName))) 
      { 
       if (OverwriteExisting) 
       { 
        File.Delete(Path.Combine(FileSystemLocation, FileName)); 
       } 
       else 
       { 
        Console.WriteLine(string.Format("File {0} already exist.", FileName)); 
        return; 
       } 
      } 

      Request = (FtpWebRequest)FtpWebRequest.Create(new Uri(Path.Combine(FtpLocation, FileName))); 
      Request.Credentials = new NetworkCredential(UserName, Password); 
      Request.Proxy = null; 
      Request.Method = WebRequestMethods.Ftp.DownloadFile; 
      Request.UseBinary = true; 

      Response = (FtpWebResponse)Request.GetResponse(); 

      using (Stream s = Response.GetResponseStream()) 
      { 
       using (FileStream fs = new FileStream(Path.Combine(FileSystemLocation, FileName), FileMode.CreateNew, FileAccess.ReadWrite)) 
       { 
        while (s.Read(Buffer, 0, BufferSize) != -1) 
        { 
         fs.Write(Buffer, 0, BufferSize); 
        } 
       } 
      } 
     } 
     catch { } 

    } 
    private string[] GetFilesList(string FtpFolderPath, string UserName, string Password) 
    { 
     try 
     { 
      FtpWebRequest Request; 
      FtpWebResponse Response; 

      Request = (FtpWebRequest)FtpWebRequest.Create(new Uri(FtpFolderPath)); 
      Request.Credentials = new NetworkCredential(UserName, Password); 
      Request.Proxy = null; 
      Request.Method = WebRequestMethods.Ftp.ListDirectory; 
      Request.UseBinary = true; 

      Response = (FtpWebResponse)Request.GetResponse(); 
      StreamReader reader = new StreamReader(Response.GetResponseStream()); 
      string Data = reader.ReadToEnd(); 

      return Data.Split('\n'); 
     } 
     catch 
     { 
      return null; 
     } 
    } 


} 
0

बदलावों के FTP साइट की निगरानी के लिए एक रोबो-एफ़टीपी स्क्रिप्ट का उपयोग कर सकते हैं। यहां एक नमूना स्क्रिप्ट का एक लिंक दिया गया है जब कोई परिवर्तन पता चला हो तो ईमेल भेजता है: http://kb.robo-ftp.com/script_library/show/40

मैंने पिछले प्रश्न को देखा जो आपने लिंक किया था। मुझे लगता है कि आपको रोबो-एफ़टीपी नमूना को संशोधित करने में सक्षम होना चाहिए और SETLEFT कमांड/स्प्लिट विकल्प के साथ कमांड विकल्प को फ़ोल्डर नाम और आईएसओ फाइल नंबर को बदले जाने के लिए उपयोग करना चाहिए और फिर फ़ाइल को उचित स्थान पर ले जाना चाहिए।

4

आप FileSystemWatcher या किसी अन्य तरीके का उपयोग नहीं कर सकते हैं, क्योंकि FTP प्रोटोकॉल में किसी निर्देशिका को दूरस्थ निर्देशिका में परिवर्तन के बारे में सूचित करने के लिए कोई API नहीं है।

आप जो भी कर सकते हैं वह समय-समय पर रिमोट पेड़ को फिर से भरना और परिवर्तन ढूंढना है।

यदि आप एक एफ़टीपी क्लाइंट लाइब्रेरी का उपयोग करते हैं जो रिमोट ट्री की रिकर्सिव सूची का समर्थन करता है तो यह वास्तव में कार्यान्वित करना आसान है। दुर्भाग्यवश, अंतर्निहित .NET FTP क्लाइंट, FtpWebRequest नहीं है। लेकिन उदाहरण के लिए WinSCP .NET assembly संस्करण 5.9 (या नया) के साथ, आप Session.EnumerateRemoteFiles method का उपयोग कर सकते हैं।

// Setup session options 
SessionOptions sessionOptions = new SessionOptions 
{ 
    Protocol = Protocol.Ftp, 
    HostName = "example.com", 
    UserName = "user", 
    Password = "password", 
}; 

using (Session session = new Session()) 
{ 
    // Connect 
    session.Open(sessionOptions); 

    List<string> prevFiles = null; 

    while (true) 
    { 
     // Collect file list 
     List<string> files = 
      session.EnumerateRemoteFiles(
       "/remote/path", "*.*", EnumerationOptions.AllDirectories) 
      .Select(fileInfo => fileInfo.FullName) 
      .ToList(); 
     if (prevFiles == null) 
     { 
      // In the first round, just print number of files found 
      Console.WriteLine("Found {0} files", files.Count); 
     } 
     else 
     { 
      // Then look for differences against the previous list 
      IEnumerable<string> added = files.Except(prevFiles); 
      if (added.Any()) 
      { 
       Console.WriteLine("Added files:"); 
       foreach (string path in added) 
       { 
        Console.WriteLine(path); 
       } 
      } 

      IEnumerable<string> removed = prevFiles.Except(files); 
      if (removed.Any()) 
      { 
       Console.WriteLine("Removed files:"); 
       foreach (string path in removed) 
       { 
        Console.WriteLine(path); 
       } 
      } 
     } 

     prevFiles = files; 

     Console.WriteLine("Sleeping 10s..."); 
     Thread.Sleep(10000); 
    } 
} 

(मैं WinSCP के लेखक हूँ)


हालांकि, आप वास्तव में सिर्फ परिवर्तन डाउनलोड करना चाहते हैं, यह एक तरह से आसान है:

लेख Watching for changes in SFTP/FTP server देखें । लूप में बस Session.SynchronizeDirectories का उपयोग करें।

session.SynchronizeDirectories(
    SynchronizationMode.Local, "/remote/path", @"C:\local\path", true).Check(); 

आप एक 3 पार्टी पुस्तकालय का उपयोग नहीं करना चाहते, तो आप FtpWebRequest की सीमाओं के साथ क्या करना है। उदाहरण के लिए FtpWebRequest के साथ एक दूरस्थ निर्देशिका पेड़ को दोबारा सूचीबद्ध करने के लिए, मेरा उत्तर C# Download all files and subdirectories through FTP पर देखें।

संबंधित मुद्दे