2017-05-25 24 views
4

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

发生了什么事?

使用.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

我没有回答你的问题,但是你可以通过使用'MemoryStream'避免在你的第二段中创建一个临时文件。 – itsme86

+1

看来问题在于如何将xml转换为字节数组。你没有表现出来,所以很难说。首先将它写入文件可能...以某种方式修复它?摇摆。可能是UploadFile使用了不同的编码... – Will

+0

@ itsme86:谢谢。在我看到其他人使用它之前,一直在四处搜寻,看看这个问题是否被问到。这是比较可取的,因为它可以让我检查已经发送用于审计/调试目的的文件。 – sconzey

回答

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不会截断现有的文件。重要的是,当您上传的数据少于现有文件时。

+1

感谢@Martin,这回答了这个问题。 '。UploadFile'更贴近用例,所以我将使用它,但是对'.WriteAllBytes'进行澄清是很好的做法 – sconzey