2012-11-26 9 views
6

मैं एसएफटीपी का उपयोग करके फ़ाइलों और निर्देशिकाओं की सूची प्राप्त करने के लिए Renci.SshNet लाइब्रेरी का उपयोग कर रहा हूं। मैं एसएफटीपी साइट को कनेक्ट करने में सक्षम हूं लेकिन मुझे यकीन नहीं है कि सी # में निर्देशिकाओं और फ़ाइलों की सूची कैसे प्राप्त करें। मुझे कोई उपयोगी उदाहरण नहीं मिला है।एसएसएननेट एसएफटीपी फ़ाइलें और निर्देशिकाएं प्राप्त करें

क्या किसी ने कोशिश की है? यदि हां, तो क्या आप इन फ़ाइलों और फ़ोल्डरों को दोबारा प्राप्त करने के तरीके के बारे में कुछ नमूना कोड पोस्ट कर सकते हैं।

धन्यवाद, Prav

उत्तर

2

इस प्रयास करें: क्योंकि ChangeDirectory और ListDirectory के बीच बातचीत के रूप में आप अपेक्षा कर सकते हैं काम नहीं करते

var filePaths = client.ListDirectory(client.WorkingDirectory); 
9

इस पुस्तकालय कुछ quirks है कि इस पुनरावर्ती सूची मुश्किल कर दिया है।

निम्नलिखित नहीं सूची/घर निर्देशिका में फ़ाइलों करता है बजाय इसे/(रूट) में फ़ाइलों को सूचीबद्ध निर्देशिका:

sftp.ChangeDirectory("home"); 
sftp.ListDirectory("").Select (s => s.FullName); 

निम्नलिखित है नहीं काम करते हैं और एक SftpPathNotFoundException रिटर्न:

sftp.ChangeDirectory("home"); 
sftp.ListDirectory("home").Select (s => s.FullName); 

निम्नलिखित/घर निर्देशिका में फ़ाइलों को सूचीबद्ध करने के लिए सही तरीका है

+०१२३५१६४१०६१
sftp.ChangeDirectory("/"); 
sftp.ListDirectory("home").Select (s => s.FullName); 

यदि आप मुझसे पूछें तो यह बहुत पागल है। ChangeDirectory विधि के साथ डिफ़ॉल्ट निर्देशिका को सेट करने से ListDirectory विधि पर कोई प्रभाव नहीं पड़ता है जब तक कि आप इस विधि के पैरामीटर में कोई फ़ोल्डर निर्दिष्ट नहीं करते हैं। ऐसा लगता है कि इसके लिए एक बग लिखा जाना चाहिए।

तो जब आप अपना रिकर्सिव फ़ंक्शन लिखते हैं तो आपको एक बार डिफ़ॉल्ट निर्देशिका सेट करनी होगी और फिर ListDirectory कॉल में निर्देशिका को बदलना होगा क्योंकि आप फ़ोल्डरों पर फिर से चलते हैं। लिस्टिंग SftpFiles की एक संख्यात्मक वापसी देता है। फिर IsDirectory == true के लिए इन्हें व्यक्तिगत रूप से चेक किया जा सकता है। बस जागरूक रहें कि लिस्टिंग . और .. प्रविष्टियां (जो निर्देशिकाएं हैं) लौटाती है। यदि आप एक अनंत लूप से बचना चाहते हैं तो आप इन्हें छोड़ना चाहेंगे। :-)

संपादित 2/23/2018

मैं अपना पुराना जवाब में से कुछ की समीक्षा की गई थी और इसके बाद के संस्करण उत्तर के लिए क्षमा चाहते हैं और अगले कार्य कोड की आपूर्ति करना चाहते हैं। ध्यान दें कि यह उदाहरण ChangeDirectory की आवश्यकता नहीं है, क्योंकि यह ListDirectory के लिए Fullname उपयोग कर रहा है:

void Main() 
{ 
    using (var client = new Renci.SshNet.SftpClient("sftp.host.com", "user", "password")) 
    { 
     var files = new List<String>(); 
     client.Connect(); 
     ListDirectory(client, ".", ref files); 
     client.Disconnect(); 
     files.Dump(); 
    } 
} 

void ListDirectory(SftpClient client, String dirName, ref List<String> files) 
{ 
    foreach (var entry in client.ListDirectory(dirName)) 
    { 

     if (entry.IsDirectory) 
     { 
      ListDirectory(client, entry.FullName, ref files); 
     } 
     else 
     { 
      files.Add(entry.FullName); 
     } 
    } 
} 
+4

sftp.ListDirectory ("") काम नहीं करता है, लेकिन sftp.ListDirectory ("।") करता है - याद रखें, '।' का मतलब है 'वर्तमान निर्देशिका'। हालांकि, यह घर फ़ोल्डर के लिए '~' शॉर्टकट का समर्थन नहीं करता प्रतीत होता है। – Gargravarr

+0

स्पष्टीकरण के लिए धन्यवाद, क्या एक पूर्ण उदाहरण है कि वास्तव में किसी दिए गए रूट फ़ोल्डर से शुरू होने वाली सभी निर्देशिकाओं और उपनिर्देशिकाओं की सूची या पेड़ कैसे प्राप्त करें? मुझे आश्चर्य है कि क्यों ssh.net सूची डायरेक्टरी विधि में एक बूल रिकर्सिव ऑफर नहीं करता है। क्या इन दिनों .NET के लिए कोई बेहतर समाधान उपलब्ध है? अर्थात। एक बेहतर lib जो भी मुफ़्त है, जो पहले से ही इन बुनियादी कार्यों को लागू करता है? हालांकि, एक कामकाजी उदाहरण बहुत उपयोगी होगा, धन्यवाद! – Erik

0

मैं इस प्रत्यावर्तन का उपयोग कर हासिल किया है। इस श्रेणी

public class TransportResponse 
{ 
    public string directoryName { get; set; } 
    public string fileName { get; set; } 
    public DateTime fileTimeStamp { get; set; } 
    public MemoryStream fileStream { get; set; } 
    public List<TransportResponse> lstTransportResponse { get; set; } 
} 

मैं ट्रांसपोर्ट रेस्पॉन्स क्लास की एक सूची बनाते हैं। DirectoryName रिक्त नहीं है, तो यह एक ही कक्षा जो एक MemoryStream के रूप में है कि निर्देशिका के अंदर फ़ाइलें (इस आपके उपयोग के मामले के अनुसार बदला जा सकता है)

List<TransportResponse> lstResponse = new List<TransportResponse>(); 
using (var client = new SftpClient(connectionInfo)) 
    { 
      try 
      { 
        Console.WriteLine("Connecting to " + connectionInfo.Host + " ..."); 
        client.Connect(); 
        Console.WriteLine("Connected to " + connectionInfo.Host + " ..."); 
      } 
      catch (Exception ex) 
      { 
        Console.WriteLine("Could not connect to "+ connectionInfo.Host +" server. Exception Details: " + ex.Message); 
      } 
      if (client.IsConnected) 
      { 
        var files = client.ListDirectory(transport.SourceFolder); 
        lstResponse = downloadFilesInDirectory(files, client); 
        client.Disconnect(); 
      } 
      else 
      { 
        Console.WriteLine("Could not download files from "+ transport.TransportIdentifier +" because client was not connected."); 
      } 
    } 



private static List<TransportResponse> downloadFilesInDirectory(IEnumerable<SftpFile> files, SftpClient client) 
    { 
     List<TransportResponse> lstResponse = new List<TransportResponse>(); 
     foreach (var file in files) 
     { 
      if (!file.IsDirectory) 
      { 
       if (file.Name != "." && file.Name != "..") 
       { 
        if (!TransportDAL.checkFileExists(file.Name, file.LastWriteTime)) 
        { 
         using (MemoryStream fs = new MemoryStream()) 
         { 
          try 
          { 
           Console.WriteLine("Reading " + file.Name + "..."); 
           client.DownloadFile(file.FullName, fs); 
           fs.Seek(0, SeekOrigin.Begin); 
           lstResponse.Add(new TransportResponse { fileName = file.Name, fileTimeStamp = file.LastWriteTime, fileStream = new MemoryStream(fs.GetBuffer()) }); 
          } 
          catch(Exception ex) 
          { 
           Console.WriteLine("Error reading File. Exception Details: " + ex.Message); 
          } 
         } 
        } 
        else 
        { 
         Console.WriteLine("File was downloaded previously"); 
        } 
       } 
      } 
      else 
      { 
       if (file.Name != "." && file.Name != "..") 
       { 
        lstResponse.Add(new TransportResponse { directoryName = file.Name,lstTransportResponse = downloadFilesInDirectory(client.ListDirectory(file.Name), client) }); 
       }     
      } 
     } 

     return lstResponse; 
    } 

आशा इस मदद करता होगा की एक सूची में शामिल होंगे।धन्यवाद

0

@Carlos बोस

इस पुस्तकालय कुछ quirks है कि इस पुनरावर्ती सूची मुश्किल बनाने क्योंकि ChangeDirectory और ListDirectory के बीच बातचीत के रूप में आप अपेक्षा कर सकते हैं काम नहीं करते है।

सही

यह अच्छी तरह से काम करता है जब ChangeDirectory() पैरामीटर है "।"

लेकिन अगर आप

SftpClient sftp ...; 
sftp.ChangeDirectory("some_folder"); 
//get file list 
List<SftpFile> fileList = sftp.ListDirectory("some_folder").ToList(); 

कर फिर वहाँ एक अभिकथन है क्योंकि ListDirectory() कॉल की उम्मीद "some_folder/some_folder"

वैकल्पिक हल का उपयोग मैं बचाने के लिए और से पहले वर्तमान निर्देशिका को बहाल करना है एक दूरस्थ अपलोड/"some_folder" के नाम बदलें, और आप ऑपरेशन से पहले उस फ़ोल्डर सूचीबद्ध करने की आवश्यकता (उदाहरण के लिए देखने के लिए फ़ाइल पहले से मौजूद)

string working_directory = sftp.WorkingDirectory; 
sftp.ChangeDirectory("some_folder"); 
sftp.RenameFile("name", "new_name"); 
sftp.ChangeDirectory(working_directory); 
यदि फ़ाइल मौजूद 0

जाँच करने के लिए, इस कॉल के लिए पर्याप्त है

sftp.Exists(path) 

या आप संवेदनशील मामले की तरह, कुछ अन्य मानदंडों को जोड़ना चाहते हैं या नहीं

public FileExistence checkFileExists(string folder, string fileName) 
    { 
     //get file list 
     List<SftpFile> fileList = sftp.ListDirectory(folder).ToList(); 

     if (fileList == null) 
     { 
     return FileExistence.UNCONFIRMED; 
     } 

     foreach (SftpFile f in fileList) 
     { 
     Console.WriteLine(f.ToString()); 
     //a not case sensitive comparison is made 
     if (f.IsRegularFile && f.Name.ToLower() == fileName.ToLower()) 
     { 
      return FileExistence.EXISTS; 
     } 
     } 

     //if not found in traversal , it does not exist 
     return FileExistence.DOES_NOT_EXIST; 
    } 

यदि जहां FileExistence

public enum FileExistence 
    { 
     EXISTS, 
     DOES_NOT_EXIST, 
     UNCONFIRMED 
    }; 
है
संबंधित मुद्दे