我在阅读网络驱动器上的大文件(~400 MB)时遇到了一个有趣的问题。最初,我将完整的网络地址输入FileInfo,并使用CopyTo函数将其传输到本地临时驱动器,然后读取它。这似乎工作正常,它不慢,但它不快-只是meh。CopyTo函数会让运行该程序的计算机的网络利用率持续上升到50%以上,这是相当不错的。
为了加快这个过程,我试图直接将网络文件读取到内存流中,以减少中间人。当我尝试这种方法时(使用描述为here的异步复制模式),它慢得令人发笑。我的网络利用率甚至从来没有超过2% -它几乎就像是什么东西在限制我。顺便说一句,我看了我的网络利用率时,直接复制相同的文件通过windows资源管理器和它击中像80- 90%。不知道这里发生了什么下面是我使用的异步复制代码:
string line;
List<string> results = new List<string>();
Parser parser = new Parser(QuerySettings.SelectedFilters, QuerySettings.SearchTerms,
QuerySettings.ExcludedTerms, QuerySettings.HighlightedTerms);
byte[] ActiveBuffer = new byte[60 * 1024];
byte[] BackBuffer = new byte[60 * 1024];
byte[] WriteBuffer = new byte[60 * 1024];
MemoryStream memStream = new MemoryStream();
FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileSystemRights.Read, FileShare.None, 60 * 1024, FileOptions.SequentialScan);
int Readed = 0;
IAsyncResult ReadResult;
IAsyncResult WriteResult;
ReadResult = fileStream.BeginRead(ActiveBuffer, 0, ActiveBuffer.Length, null, null);
do
{
Readed = fileStream.EndRead(ReadResult);
WriteResult = memStream.BeginWrite(ActiveBuffer, 0, Readed, null, null);
WriteBuffer = ActiveBuffer;
if (Readed > 0)
{
ReadResult = fileStream.BeginRead(BackBuffer, 0, BackBuffer.Length, null, null);
BackBuffer = Interlocked.Exchange(ref ActiveBuffer, BackBuffer);
}
memStream.EndWrite(WriteResult);
}
while (Readed > 0);
StreamReader streamReader = new StreamReader(memStream);
while ((line = streamReader.ReadLine()) != null)
{
if (parser.ParseResults(line))
results.Add(line);
}
fileStream.Flush();
fileStream.Close();
memStream.Flush();
memStream.Close();
return results;
更新根据评论,我刚刚尝试了以下内容。它只有我的网络利用率在大约10- 15%...为什么这么低?
MemoryStream memStream = new MemoryStream();
FileStream fileStream = File.OpenRead(fullPath);
fileStream.CopyTo(memStream);
memStream.Seek(0, 0);
StreamReader streamReader = new StreamReader(memStream);
Parser parser = new Parser(QuerySettings.SelectedFilters, QuerySettings.SearchTerms,
QuerySettings.ExcludedTerms, QuerySettings.HighlightedTerms);
while ((line = streamReader.ReadLine()) != null)
{
if (parser.ParseResults(line))
results.Add(line);
}
3条答案
按热度按时间zte4gxcn1#
我迟到了,但最近也遇到了同样的网络利用率低的问题,在尝试了很多不同的实现之后,如果最后发现一个带有大缓冲区(在我的情况下是1MB)的StreamReader将网络利用率提高到了99%。其他选项均未产生重大变化。
7gs2gvoe2#
复制整个文件然后解析它是没有意义的。只需从网络驱动器打开文件,让.Net Framework为您提供最佳数据。你可以比MS开发人员更聪明,你可以比他们更快地创建一个复制方法,但这确实是一个挑战。
piv4azn73#
使用Reflector,我看到您对以下内容的调用:
最终使用大小为4096字节(0x1000)的缓冲区。
您可以尝试显式调用FileStream构造函数之一,并指定更大的缓冲区大小和FileOption.SequentialScan。
不确定这会有帮助,但很容易尝试。