What is the difference between SftpClient.UploadFile and SftpClient.WriteAllBytes?

妖精的绣舞 提交于 2019-12-22 09:04:20

问题


I am observing some strange behaviour when I use SSH.NET to transfer files with SFTP. I am using SFTP to transfer XML files to another service (which I don't control) for processing. If I use SftpClient.WriteAllBytes the service complains the file is not valid XML. If I first write to a temporary file and then use SftpClient.UploadFile the transfer is successful.

What's happening?

Using .WriteAllBytes:

public void Send(string remoteFilePath, byte[] contents)
{
    using(var client = new SftpClient(new ConnectionInfo(/* username password etc.*/)))
    {
        client.Connect();
        client.WriteAllBytes(remoteFilePath, contents);
    }
}

Using .UploadFile:

public void Send(string remoteFilePath, byte[] contents)
{
    var tempFileName = Path.GetTempFileName();
    File.WriteAllBytes(tempFileName, contents);
    using(var fs = new FileStream(tempFile, FileMode.Open))
    using(var client = new SftpClient(new ConnectionInfo(/* username password etc.*/)))
    {
        client.Connect();
        client.UploadFile(fs, targetPath);
    }
}

Edit: Will in the comments asked how I turn the XML into a byte-array. I didn't think this was relevant, but then again I'm the one asking the question... :P

// somewhere else:
// XDocument xdoc = CreateXDoc();

using(var st = new MemoryStream())
{
    using(var xw = XmlWriter.Create(st, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }))
    {
        xdoc.WriteTo(xw);
    }
    return st.ToArray();
}

回答1:


I can reproduce your problem using SSH.NET 2016.0.0 from NuGet. But not with 2016.1.0-beta1.

Inspecting the code, I can see that the SftpFileStream (what the WriteAllBytes uses) keeps writing the same (starting) piece of the data all the time.

It seems that your are suffering from this bug:
https://github.com/sshnet/SSH.NET/issues/70

While the bug description does not make it clear that it's your problem, the commit that fixes it matches the problem I have found:
Take into account the offset in SftpFileStream.Write(byte[] buffer, int offset, int count) when not writing to the buffer. Fixes issue #70.


To answer your question: The methods should indeed behave similarly.

Except that SftpClient.UploadFile is optimized for uploads of large amount of data, while the SftpClient.WriteAllBytes is not. So the underlying implementation is very different.

Also the SftpClient.WriteAllBytes does not truncate an existing file. What matters, when you are uploading less data than the existing file have.



来源:https://stackoverflow.com/questions/44185392/what-is-the-difference-between-sftpclient-uploadfile-and-sftpclient-writeallbyte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!