SSH.NET library encode the file name

1.9k Views Asked by At

I must download a file using SSH.NET library. After I download a file I must delete the remote file. Everything works but the file name is encoded. I mean that for example, if I have a file named New file, I download/upload a file named New%20file. Now, if I download/upload the new file I obtain New%25%20file and again New%252520file... and so on... This is very problematic. How can I avoid to change the file name after I download it?

Here the code I am using to download:

string fileName = base.Uri.GetFileName();
string fullPath = Path.Combine(pathFolder, fileName);

using (SftpClient client = new SftpClient(
              new PasswordConnectionInfo(
                    base.Uri.Host, SftpFlowGateway.CONST_PORT_NUMBER,
                    base.Credential.UserName,
                    base.Credential.Password))
      )
{
    client.Connect();

    using (FileStream fileStreamToDownload = new FileStream(fullPath, FileMode.Create))
    {
        client.DownloadFile(base.Uri.LocalPath, fileStreamToDownload);
    }

    client.Disconnect();
}

EDIT:

base.Uri is just defined as follow:

private Uri _uri;
public Uri Uri 
{
    get { return _uri; }
    protected set { _uri = value; } 
}

And the GetFileName method is:

public static string GetFileName(this Uri path)
{
    return path.Segments.Last();
}

When I debug, I can see that the properties of the class Uri have the correct value... It is not encoded

Thank you

2

There are 2 best solutions below

0
On BEST ANSWER

You are passing a stream you have created yourself (new FileStream) to the SSH.NET. The library does not even know it's a file it is writing to, nor its name. So it's not the library that URL-encodes the file name. It has to be URL-encoded in the fullPath variable already.

It's the Uri.AbsolutePath and Uri.Segments that return URL-encoded path. That's how the System.Uri class works. I assume you use the constructor overload Uri(string uriString).

Use the static method Uri.UnescapeDataString to reverse encoding done by the Uri constructor.

Note the obsoleted constructor overload Uri(string uriString, bool dontEscape).

1
On

It looks like the SSH.Net library simply URL encodes the file names.

I suppose you could rename the file after you've downloaded it using the System.Web.UrlDecode method?

Or UrlEncode the filename when you upload.

Unfortunately, I haven't used the library myself but you could help further by letting us know if the name change occurs on download or upload or both.

EDIT: As martin mentioned, its not the library doing any encoding.

I've just tried it myself.

string fileName = "file with spaces.txt";
using (Stream outputFile = File.OpenWrite(localDir + "\\" + fileName))
{
    sftpClient.DownloadFile(fileName, outputFile);
}

The created file is also named "file with spaces.txt" though that would've been the case anyway since it was created via the stream.