最近平台上使用QTableView + QFileSystemModel
来自定义目录管理器
然后发现部分客户端上访问指定目录很慢,基本要10-20秒才能响应,而且是偶发性的问题。
经测试,在有访问效率问题的电脑上,使用QTableView
会特别明显,QListView
还没那么明显。
这里怀疑了很多原因,QTableView、QFileSystemModel、多线程等,都猜错了。
找了很久原因没找到,测试原生的QFileDialog
,一样会有效率问题。
此时决定自己实现文件目录表,通过QDir
来遍历目录。
最终发现,QDir
的entryList
和entryInfoList
都一样存在效率问题。
逐句调试源码发现,原来是访问其中一个文件特别慢。
出现异常的源码位置为diriterator.cpp
void DirIteratorPrivate::advance()
{
if(engine)
{
while(!fileEngineIterators.isEmpty())
{
// Find the next valid iterator that matches the filters.
AbstractFileEngineIterator *it;
while(it = fileEngineIterators.top(), it->hasNext())
{
it->next();
//此处出现异常/
if(entryMatches(it->currentFileName(), it->currentFileInfo()))
{
return;
}
}
fileEngineIterators.pop();
delete it;
}
}
else
{
FileSystemEntry nextEntry;
FileSystemMetaData nextMetaData;
while(!nativeIterators.isEmpty())
{
// Find the next valid iterator that matches the filters.
FileSystemIterator *it;
while(it = nativeIterators.top(), it->advance(nextEntry, nextMetaData))
{
FileInfo info(new FileInfoPrivate(nextEntry, nextMetaData));
if(entryMatches(nextEntry.fileName(), info))
{
return;
}
}
nativeIterators.pop();
delete it;
}
}
currentFileInfo = nextFileInfo;
nextFileInfo = FileInfo();
}
问题出现在:快捷方式:网络位置
上
对于快捷方式,本身访问的速度就比本地的要慢,因此访问的效率肯定是更慢的。
在部分客户端上,恰好有配一个到服务器的网络地址快捷方式,恰好服务器的ip更换了,因此找不到这个网络位置,因此访问会特别的慢
即便是Windows,在操作(选中、右键、移动快捷方式)这种失效的网络位置的快捷方式时,也需要响应很久
猜测是由于QDir
在遍历当前文件夹下的文件的时候,会找到存在的文件夹、文件、快捷方式,并且验证其有效性
。
而对于网络位置的快捷方式
,验证有效性的方式无疑就是访问网络位置,位置不正确的情况下,响应是很久的,因此会造成效率特别低的情况。
解决方案:
改Qt源码,遍历文件和文件夹加个过滤的网络位置的选项。