在对某些源代码进行性能分析的同时,我注意到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_RECALL
。 FILE_FLAG_NO_BUFFERING
也可能有帮助,但它需要扇区对齐的I / O。
Visual Studio的较新版本将fopen模式字符串中的R
映射为FILE_FLAG_RANDOM_ACCESS
。