使用 StreamWriter 写入文件比通过慢速网络复制文件慢得多

本文关键字:文件 网络 复制 StreamWriter 使用 | 更新日期: 2023-09-27 17:56:27

我有一个程序,它试图将大量文本写入海外远程服务器上的文件,该服务器上的网络连接速度很慢。

使用以下代码,其中outputFileContentStringBuilder

using (var outfile = new StreamWriter(myRemoteFilePath))
{
    outfile.Write(outputFileContent.ToString());
}

运行需要很长时间(几分钟),而如果我先写入本地文件,然后将其复制到远程位置,则速度要快得多(20-30 秒):

string tempFilePath = Path.GetTempFileName();
using (var outfile = new StreamWriter(tempFilePath))
{
    outfile.Write(outputFileContent.ToString());
}
System.IO.File.Copy(tempFilePath, myRemoteFilePath, true)

知道为什么会这样吗?我唯一的猜测是,这与网络上的缓冲有关,或者可能是因为流编写器不知道它需要提前有多大。

使用 StreamWriter 写入文件比通过慢速网络复制文件慢得多

如果使用默认缓冲区大小创建 StreamWriter,则基础 SMB 协议将以不超过 4096 字节的块发出写入请求,这意味着通过网络进行大量往返。 您可以将 StreamWriter 的缓冲区大小增加到最大 64k,以减少往返次数:

using (var outfile = new StreamWriter(myRemoteFilePath, false, Encoding.ASCII, 0x10000))

在任何情况下,将缓冲区大小增加到 64k 以上都无济于事,因为基础 SMB 协议不支持超过 64k 的缓冲区长度。 请注意,直接文件副本仍使用 SMB 协议,因此从网络流量的角度来看,除了缓冲区大小外,操作之间几乎没有区别。

我不是安全专家,但在我看来,这与权限问题最相关。

每次向远程服务器上的磁盘写入某些内容时,都会根据执行该操作的用户检查权限。写作的许可,自然。

如果不是复制,则仅执行该控件。所以它要快得多

实际上,为了证明这一点,您可以尝试通过网络复制多个文件,然后在通过网络复制ZIP文件(压缩状态下具有相同数量的内存)之后。在第二种情况下,它会快得多,因为对于单个 ZIP 文件,权限控制只执行一次。

希望这有帮助。