我在我的Qt应用程序中使用taglib库(1.7.2),从音乐文件夹中读取一些mp3文件的元数据。 问题是我发现它很慢。
例如,这是代码:
QString path = "C:/Music/";
QDir d(path);
QStringList fileTypes;
fileTypes << "*.mp3" ;
d.setNameFilters(fileTypes);
QStringList pathList = d.entryList( QDir::NoDotAndDotDot | QDir::Files);
QTime t;
t.start();
foreach (QString fileName, pathList) {
fileName = path + fileName;
TagLib::FileRef *f = new TagLib::FileRef(fileName.toStdWString().c_str());
}
qDebug()<<t.elapsed();
此代码大约需要11秒才能加载包含400首歌曲的文件夹,即每个文件大约需要28毫秒。 这条线很慢:
TagLib::FileRef *f = new TagLib::FileRef(pathFile.toStdWString().c_str());
这是正常的吗? 我尝试过使用多线程,但它并没有改变任何东西,它并不是来自我的电脑,因为它足够强大。 奇怪的是,一旦所有文件都被加载,下次再次加载文件夹时,它就会立即完成(直到我重新启动操作系统)。
我还有另一个问题。
有时,当未设置标记时,应用程序崩溃并输出:
HEAP[myapp.exe]:
Invalid address specified to RtlFreeHeap( 0ED90000, 0ED92CC0 )
在以下行中,例如:
if (!f->tag()->genre().isNull())
我正在使用Windows 7。
感谢。
答案 0 :(得分:3)
有时,当未设置标记时,应用程序崩溃并输出...
这是TagLib中许多奇怪的设计决策之一。没有标签时,AudioProperties对象为NULL。您必须使用它并添加一些额外的代码来检查NULL。
奇怪的是,一旦所有文件都被加载,下次再次加载文件夹时,它会立即完成(直到我重新启动操作系统)
这并不奇怪,因为Windows 7具有非常先进且非常具有侵略性的磁盘I / O缓存机制。一旦你“触摸”了文件,它就会进入RAM,下次你访问它时 - 它几乎是瞬间完成的。 400个mp3文件并不多,它们都适合RAM。
11s加载包含400首歌曲的文件夹
400次你必须执行磁盘搜索,在典型的硬盘驱动器上通常需要9-11ms(是的,SSD只有0.1ms)。因此,如果文件夹是碎片状的,那么至少要有10 * 400 = 4秒来“倒回”驱动器的磁头。由于id3标签可能出现在文件的开头和结尾,这实际上会增加两次读取次数(你必须倒回到文件的末尾),从而给出2倍的时间(大约8秒)。
简历:阅读文件夹的时间接近现实。 TagLib中有许多怪癖(如NULL或无法重载文件操作以允许,例如从档案中读取),但它们是可以避免的。 TagLib的功能非常好,在很多方面它都是独一无二的(宽格式支持)。