SftpClient.UploadFile和SftpClient.WriteAllBytes有什么区别?

时间:2017-05-25 16:26:01

标签: c# .net ssh sftp ssh.net

当我使用SSH.NET使用SFTP传输文件时,我观察到一些奇怪的行为。我正在使用SFTP将XML文件传输到另一个服务(我无法控制)进行处理。如果我使用SftpClient.WriteAllBytes服务抱怨该文件不是有效的XML。如果我先写入临时文件,然后使用SftpClient.UploadFile,则传输成功。

发生了什么?

使用.WriteAllBytes

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

使用.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);
    }
}

修改 请问评论中我将如何将XML转换为字节数组。我并不认为这是相关的,但我又是那个问这个问题的人......: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 个答案:

答案 0 :(得分:1)

我可以使用NuGet的SSH.NET 2016.0.0重现您的问题。但不是2016.1.0-beta1。

检查代码,我可以看到SftpFileStreamWriteAllBytes使用的)始终保持写入相同(起始)的数据。

看来你正在遭受这个错误:
https://github.com/sshnet/SSH.NET/issues/70

虽然错误描述并未明确表明它是您的问题,但修复它的提交符合我发现的问题:
Take into account the offset in SftpFileStream.Write(byte[] buffer, int offset, int count) when not writing to the buffer. Fixes issue #70.

回答你的问题:方法确实应该表现得相似。

除了SftpClient.UploadFile针对大量数据的上传进行了优化,而SftpClient.WriteAllBytes则没有。所以底层实现是非常不同的。

SftpClient.WriteAllBytes也不会截断现有文件。重要的是,当您上传的数据少于现有文件时。