我正在使用 Renci SSH.NET 访问 unix 服务器上的文件和文件夹。我想通过指定基本目录来删除整个目录树,但是当我调用 时sftp.DeleteDirectory(destination)
,只有当我传递一个空目录时,该调用才会成功。
但是,我还希望能够删除包含文件或其他文件夹的目录。大多数 .NET 类都会自动处理,如何在 SSH.NET 中完成?
SSH.NET 库不支持任何递归操作。所以递归删除也不可用。
您必须使用该SftpClient.ListDirectory
方法递归列出所有文件和子文件夹并一一删除。
private static void DeleteDirectory(SftpClient client, string path)
{
foreach (SftpFile file in client.ListDirectory(path))
{
if ((file.Name != ".") && (file.Name != ".."))
{
if (file.IsDirectory)
{
DeleteDirectory(client, file.FullName);
}
else
{
client.DeleteFile(file.FullName);
}
}
}
client.DeleteDirectory(path);
}
或者使用另一个 SFTP 库。
例如使用WinSCP .NET 程序集,您可以使用可以递归删除目录的Session.RemoveFiles
方法。
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "example.com",
UserName = "user",
Password = "mypassword",
SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...="
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Delete the directory recursively
session.RemoveFiles("/directory/to/delete").Check();
}
(我是WinSCP的作者)
尝试在 SSH 中执行命令,而不是使用 sftp rm -rf 或 rm -r。
代码可能如下所示:
Renci.SshClient ssh1 = new SshCLient("server","user","password");
ssh1.connect();
ssh1.RunCommand("cd LandingZone;rm -rf <directoryName>");
ssh1.Disconnect();
您可以通过使用以下两种方法指定远程路径,使用 SSH.NET 库(无论它是否为空目录)动态删除目录树或文件:
public bool DeleteRemoteDirectoryRecursive(string RemoteDirectoryPath)
{
if (string.IsNullOrEmpty(RemoteDirectoryPath))
{
return false;
}
var ConnectionInfo = new ConnectionInfo(this.sftpHost, this.sftpPort, this.sftpUser, new PasswordAuthenticationMethod(this.sftpUser, this.sftpPassword));
using (var client = new SftpClient(ConnectionInfo))
{
client.Connect();
if (!client.Exists(RemoteDirectoryPath))
{
client.Disconnect();
client.Dispose();
return false;
}
foreach (var file in client.ListDirectory(RemoteDirectoryPath))
{
if (file.Name.Equals(".") || file.Name.Equals(".."))
continue;
if (file.IsDirectory)
{
client.Disconnect();
DeleteRemoteDirectoryRecursive(file.FullName);
}
else
client.DeleteFile(file.FullName);
}
client.DeleteDirectory(RemoteDirectoryPath);
}
return true;
}
public bool Remove(string RemotePath)
{
bool ReturnResult = false;
try
{
if (string.IsNullOrEmpty(RemotePath))
{
return false;
}
var ConnectionInfo = new ConnectionInfo(this.sftpHost, this.sftpPort, this.sftpUser, new PasswordAuthenticationMethod(this.sftpUser, this.sftpPassword));
using (var client = new SftpClient(ConnectionInfo))
{
client.Connect();
if (!client.Exists(RemotePath))
{
client.Disconnect();
client.Dispose();
return false;
}
try
{
// path is directory
client.ChangeDirectory(RemotePath);
try
{
DeleteRemoteDirectoryRecursive(RemotePath);
ReturnResult = true;
}
catch
{
ReturnResult = false;
}
}
// path is a file
catch
{
try
{
client.DeleteFile(RemotePath);
ReturnResult = true;
}
catch
{
ReturnResult = false;
}
}
}
}
catch (Exception ex)
{
ReturnResult = false;
}
return ReturnResult;
}