2017-05-25 23 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