问题
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