C ++ CreateFile和fopen函数抢先读取整个远程文件

在对某些源代码进行性能分析的同时,我注意到CreateFile和fopen在远程文件上花费的时间非常长。

通过wireshark进一步挖掘,我发现当使用这两个函数中的任何一个来打开文件进行读取时,文件的全部内容(最多大约4MB)正被读取。 让我也注意到,在SMB2读取操作完成之前,这两个函数都不会返回(这占用了大概99%的通话时间)。

反正有防止这种行为? 任何人都可以解释这里发生了什么?

.. ..

例:

HANDLE h = ::CreateFile( "\\\\Server1\\Data0\\CRUISE_DATA.bin", GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL ); 

来自Wireshark:

SMB2 426创build请求文件:Jim \ Data0 \ CRUISE_DATA.bin

SMB2 386创build响应文件:Jim \ Data0 \ CRUISE_DATA.bin

SMB2 171读取请求长度:65536closures:0文件:Jim \ Data0 \ CRUISE_DATA.bin

SMB2 1434读取响应

SMB2 171读取请求长度:65536closures:3735552文件:Jim \ Data0 \ CRUISE_DATA.bin

SMB2 1434读取响应

这绝对是扫描的东西…实际上病毒扫描。 一旦我关闭了我的病毒扫描器并重复测试,行为就消失了。 显然,实时保护扫描每个文件,因为它在给定的过程中打开。 至少它可以做的是更新本地缓存;)

这个问题已经困扰了我们一段时间了。 它表示,在我提问后的第二天,答案就在我们的圈子里。 无论如何,我希望这可以帮助别人。

您可以尝试一些CreateFile标志选项: FILE_FLAG_RANDOM_ACCESS和/或FILE_FLAG_OPEN_NO_RECALLFILE_FLAG_NO_BUFFERING也可能有帮助,但它需要扇区对齐的I / O。

Visual Studio的较新版本将fopen模式字符串中的R映射为FILE_FLAG_RANDOM_ACCESS