SSH.NET SFTP递归获取目录和文件列表
我正在使用Renci.SshNet库通过使用SFTP递归获取文件和目录列表。 我能够连接SFTP站点,但我不知道如何在C#中递归获取目录和文件列表。 我没有找到任何有用的例子。
有人试过吗? 如果是这样,你可以发布一些关于如何递归获取这些文件和文件夹的示例代码。
谢谢,
Prav
这个库有一些怪癖使得这个递归列表变得棘手,因为ChangeDirectory
和ListDirectory
之间的交互不能像你期望的那样工作。
以下内容未列出/ home目录中的文件,而是列出/(root)目录中的文件:
sftp.ChangeDirectory("home"); sftp.ListDirectory("").Select (s => s.FullName);
以下不起作用并返回SftpPathNotFoundException:
sftp.ChangeDirectory("home"); sftp.ListDirectory("home").Select (s => s.FullName);
以下是列出/ home目录中文件的正确方法
sftp.ChangeDirectory("/"); sftp.ListDirectory("home").Select (s => s.FullName);
如果你问我,这真是太疯狂了。 除非在此方法的参数中指定文件夹,否则使用ChangeDirectory
方法设置默认目录对ListDirectory
方法没有影响。 好像应该为此编写一个bug。
因此,当您编写递归函数时,您必须设置一次默认目录,然后在迭代文件夹时更改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(); client.Connect(); ListDirectory(client, ".", ref files); client.Disconnect(); files.Dump(); } } void ListDirectory(SftpClient client, String dirName, ref List files) { foreach (var entry in client.ListDirectory(dirName)) { if (entry.IsDirectory) { ListDirectory(client, entry.FullName, ref files); } else { files.Add(entry.FullName); } } }
试试这个:
var filePaths = client.ListDirectory(client.WorkingDirectory);
我已经使用递归实现了这一点。 像这样创建了一个类TransportResponse
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 lstTransportResponse { get; set; } }
我创建了一个TransportResponse类列表。 如果directoryName不为null,它将包含一个相同类的列表,该列表将该目录中的文件作为MemoryStream(这可以根据您的用例进行更改)
List lstResponse = new List (); 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 downloadFilesInDirectory(IEnumerable files, SftpClient client) { List lstResponse = new List (); 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; }
希望这可以帮助。 谢谢
@Carlos Bos
这个库有一些怪癖使得这个递归列表变得棘手,因为ChangeDirectory和ListDirectory之间的交互不能像你期望的那样工作。
正确
当ChangeDirectory()参数为“。”时,它运行良好。
但如果你这样做
SftpClient sftp ...; sftp.ChangeDirectory("some_folder"); //get file list List 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);
要检查文件是否存在,此调用就足够了
sftp.Exists(path)
或者如果你想添加一些其他标准,如区分大小写或不区分大小写
public FileExistence checkFileExists(string folder, string fileName) { //get file list List 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的位置
上述就是C#学习教程:SSH.NET SFTP递归获取目录和文件列表分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public enum FileExistence { EXISTS, DOES_NOT_EXIST, UNCONFIRMED };
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/960788.html