Renci SSH.NET: Is it possible to create a folder c

2019-05-26 03:25发布

I am currently using Renci SSH.NET to upload files and folders to a Unix Server using SFTP, and creating directories using

sftp.CreateDirectory("//server/test/test2");

works perfectly, as long as the folder "test" already exists. If it doesn't, the CreateDirectory method fails, and this happens everytime when you try to create directories containing multiple levels.

Is there an elegant way to recursively generate all the directories in a string? I was assuming that the CreateDirectory method does that automatically.

3条回答
萌系小妹纸
2楼-- · 2019-05-26 03:40

FWIW, here's my rather simple take on it. The one requirement is that the server destination path is seperated by forward-slashes, as is the norm. I check for this before calling the function.

    private void CreateServerDirectoryIfItDoesntExist(string serverDestinationPath, SftpClient sftpClient)
    {
        if (serverDestinationPath[0] == '/')
            serverDestinationPath = serverDestinationPath.Substring(1);

        string[] directories = serverDestinationPath.Split('/');
        for (int i = 0; i < directories.Length; i++)
        {
            string dirName = string.Join("/", directories, 0, i + 1);
            if (!sftpClient.Exists(dirName))
                sftpClient.CreateDirectory(dirName);
        }
    }

HTH

查看更多
放我归山
3楼-- · 2019-05-26 03:48

There's no other way.

Just iterate directory levels, testing each level using SftpClient.GetAttributes and create the levels that does not exist.

static public void CreateDirectoryRecursively(this SftpClient client, string path)
{
    string current = "";

    if (path[0] == '/')
    {
        path = path.Substring(1);
    }

    while (!string.IsNullOrEmpty(path))
    {
        int p = path.IndexOf('/');
        current += '/';
        if (p >= 0)
        {
            current += path.Substring(0, p);
            path = path.Substring(p + 1);
        }
        else
        {
            current += path;
            path = "";
        }

        try
        {
            SftpFileAttributes attrs = client.GetAttributes(current);
            if (!attrs.IsDirectory)
            {
                throw new Exception("not directory");
            }
        }
        catch (SftpPathNotFoundException)
        {
            client.CreateDirectory(current);
        }
    }
}
查看更多
叼着烟拽天下
4楼-- · 2019-05-26 03:51

A little improvement on the code provided by Martin Prikryl

Don't use Exceptions as a flow control mechanism. The better alternative here is to check if the current path exists first.

if (client.Exists(current))
{
    SftpFileAttributes attrs = client.GetAttributes(current);
    if (!attrs.IsDirectory)
    {
        throw new Exception("not directory");
    }
}
else
{
    client.CreateDirectory(current);
}

instead of the try catch construct

try
{
    SftpFileAttributes attrs = client.GetAttributes(current);
    if (!attrs.IsDirectory)
    {
        throw new Exception("not directory");
    }
}
catch (SftpPathNotFoundException)
{
    client.CreateDirectory(current);
}
查看更多
登录 后发表回答