Renci.Ssh.Net:生成SFTP XML文件,WriteAllText与UploadFile性能对比
问题描述
我现在用C#结合Renci.Ssh.Net库实现SFTP操作,需要在SFTP服务器上直接生成多个约60KB的XML文件。目前我是动态生成XML字符串,然后用WriteAllText()方法直接写入SFTP,这样可以避免本地IO操作,代码如下:
using (SftpClient client = new SftpClient(host,port, sftpUser, sftpPassword)) { client.Connect(); if (client.IsConnected) { client.BufferSize = 1024; var filePath = sftpDir + fileName; client.WriteAllText(filePath, contents); client.Disconnect(); } client.Dispose(); }
我想请教:从长期来看,改用基于MemoryStream的UploadFile()方法会不会带来更好的性能?
回答
其实对于你这种60KB级别的小XML文件来说,两种方法的性能差异几乎可以忽略不计,但我们可以从底层实现和适用场景来拆解分析:
底层逻辑高度重合
翻一下Renci.Ssh.Net的源码就会发现,WriteAllText()内部其实已经帮你做了这些事:把字符串转成字节数组、塞进MemoryStream,然后调用UploadFile()完成上传。也就是说,你现在用的方法本质上和自己手动写MemoryStream再调用UploadFile()是一回事——只是库帮你封装了转换步骤而已。只有大文件才会拉开差距
只有当你处理几十MB甚至更大的文件时,直接用FileStream(或分段读取的流)配合UploadFile()才会体现出优势(比如避免一次性把整个文件加载到内存)。但你的文件只有60KB,完全在内存的舒适处理范围内,所以没必要折腾。代码简洁性才是当前的重点
你现在的WriteAllText()写法更简洁,不需要手动处理流的创建、转换和释放,代码可读性更高,维护成本也更低。对于当前的场景来说,这比微乎其微的性能差异重要得多。给个小优化建议
你设置的BufferSize = 1024有点偏小了,Renci.Ssh.Net默认的缓冲区是32KB,对于60KB的文件来说,把缓冲区调到64KB(client.BufferSize = 65536;)可以减少网络交互的次数,反而能小幅提升效率。
总结一下:当前场景下WriteAllText()完全够用,性能和UploadFile(MemoryStream)没区别,还更省心。如果之后需要处理超大文件,再考虑切换到流的方式也完全来得及。
内容的提问来源于stack exchange,提问作者Priya

