4

我在我的 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();

这段代码加载一个包含 400 首歌曲的文件夹大约需要 11 秒,即每个文件大约需要 28 毫秒。这是一条非常慢的线:

TagLib::FileRef *f = new TagLib::FileRef(pathFile.toStdWString().c_str());

这么长正常吗?我尝试过使用多线程,但它并没有改变任何东西,而且它不是来自我的 PC,因为它足够强大。奇怪的是,一旦加载了所有文件,下次再次加载文件夹时,它就会立即完成(直到我重新启动操作系统)。


我还有另一个问题。

有时,当未设置标签时,应用程序崩溃并输出:

HEAP[myapp.exe]: 
Invalid address specified to RtlFreeHeap( 0ED90000, 0ED92CC0 )

例如以下行:

if (!f->tag()->genre().isNull())

我正在使用 Windows 7。

谢谢。

4

1 回答 1

3

有时,当未设置标签时,应用程序崩溃并输出...

这是 TagLib 中许多奇怪的设计决策之一。没有标签时,AudioProperties 对象为 NULL。您必须忍受它并添加一些额外的代码来检查 NULL。

奇怪的是,一旦加载了所有文件,下次再次加载文件夹时,它就会立即完成(直到我重新启动操作系统)

这并不奇怪,因为 Windows 7 具有非常先进且非常激进的磁盘 I/O 缓存机制。一旦您“触摸”该文件,它就会进入 RAM,下次您访问它时,它几乎是瞬间完成的。400 个 mp3 文件并不多,而且都适合 RAM。

11 秒加载包含 400 首歌曲的文件夹

您必须执行 400 次磁盘寻道,这在典型的硬盘驱动器上通常需要 9-11 毫秒(是的,SSD 只需 0.1 毫秒)。因此,如果文件夹碎片,您至少有 10*400 = 4 秒来“倒带”驱动器的头部。由于 id3 标签可能出现在文件的开头和结尾,这实际上增加了两次读取次数(您必须倒回到文件末尾),从而提供 2 倍时间(大约 8 秒)。

简历:阅读文件夹的时间接近于现实。TagLib 中有许多怪癖(如 NULL 或无法重载文件操作以允许,例如从档案中读取),但它们是可以避免的。TagLib 的功能非常好,而且在很多方面都是独一无二的(支持广泛的格式)。

于 2012-07-01T19:50:30.713 回答