QFileInfo size() 正在返回快捷方式目标大小
QFileInfo size() is returning shortcut TARGET size
我正在扫描这样的文件夹大小:
qint64 dirSize = 0;
int fileCount = 0;
for(QDirIterator itDir(someDir, QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::System,
QDirIterator::Subdirectories);
itDir.hasNext(); )
{
itDir.next();
dirSize += itDir.fileInfo().size();
++fileCount;
}
这似乎工作正常。
但是,我注意到包含 Windows 个快捷方式 (.lnk
) 的文件夹返回的大小比预期的大得多。原因是返回的是快捷方式目标的大小,而不是快捷方式文件本身的大小。
On Windows, symlinks (shortcuts) are .lnk files. The reported size() is that of the symlink (not the link's target) [...]
所以我的问题是:我在这里做错了什么?如何获取快捷方式文件的大小?
出于测试目的,我创建了一个 Qt 的 DLL 文件的快捷方式。我将此快捷方式放入一个空文件夹中。我还创建了 Qt 的快捷方式 sdktool.exe 并将其放入同一文件夹中。
我还注意到 size() returns 实际文件的大小而不是快捷方式的大小。我记得我在旧项目中有一些类似的行为,我所做的是在读取大小之前打开文件。
for (QDirIterator itr(someDir, QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::System,
QDirIterator::Subdirectories); itr.hasNext();) {
itr.next();
// Shows wrong size
qDebug() << itr.fileName() << ", size (unopened): " << itr.fileInfo().size();
QFile file(itr.filePath());
if (file.exists() && file.open(QIODevice::ReadOnly)) {
// Now the size shows correctly
qDebug() << "Size when opened: " << file.size();
file.close();
}
}
输出:
"sdktool.lnk" , size (unopened): 2817024
Size when opened: 1325
"test.lnk" , size (unopened): 4429312
Size when opened: 951
Windows10的文件属性window显示"test.lnk"大小为951字节,"sdktool.lnk"大小为1325字节
@Rob 的答案在大多数情况下都有效,但是 returns 0 当快捷方式的目标不 exist/is 无效时。
从这种方法中得到启发,您还可以复制快捷方式并更改扩展名。
所以将它全部组合成一个函数(我在这里假设打开目标是 cheaper/safer 而不是复制快捷方式):
qint64 getFileSize(const QString &path)
{
qint64 size = 0;
QFileInfo fileInfo(path);
if(fileInfo.isSymLink() && fileInfo.size() == QFileInfo(fileInfo.symLinkTarget()).size())
{
// Try this approach first
QFile file(path);
if(file.exists() && file.open(QIODevice::ReadOnly))
size = file.size();
file.close();
// If that didn't work, try this
if(size == 0)
{
QString tmpPath = path+".tmp";
for(int i=2; QFileInfo().exists(tmpPath); ++i) // Make sure filename is unique
tmpPath = path+".tmp"+QString::number(i);
if(QFile::copy(path, tmpPath))
{
size = QFileInfo(tmpPath).size();
QFile::remove(tmpPath);
}
}
}
else size = fileInfo.size();
return size;
}
我正在扫描这样的文件夹大小:
qint64 dirSize = 0;
int fileCount = 0;
for(QDirIterator itDir(someDir, QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::System,
QDirIterator::Subdirectories);
itDir.hasNext(); )
{
itDir.next();
dirSize += itDir.fileInfo().size();
++fileCount;
}
这似乎工作正常。
但是,我注意到包含 Windows 个快捷方式 (.lnk
) 的文件夹返回的大小比预期的大得多。原因是返回的是快捷方式目标的大小,而不是快捷方式文件本身的大小。
On Windows, symlinks (shortcuts) are .lnk files. The reported size() is that of the symlink (not the link's target) [...]
所以我的问题是:我在这里做错了什么?如何获取快捷方式文件的大小?
出于测试目的,我创建了一个 Qt 的 DLL 文件的快捷方式。我将此快捷方式放入一个空文件夹中。我还创建了 Qt 的快捷方式 sdktool.exe 并将其放入同一文件夹中。
我还注意到 size() returns 实际文件的大小而不是快捷方式的大小。我记得我在旧项目中有一些类似的行为,我所做的是在读取大小之前打开文件。
for (QDirIterator itr(someDir, QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::System,
QDirIterator::Subdirectories); itr.hasNext();) {
itr.next();
// Shows wrong size
qDebug() << itr.fileName() << ", size (unopened): " << itr.fileInfo().size();
QFile file(itr.filePath());
if (file.exists() && file.open(QIODevice::ReadOnly)) {
// Now the size shows correctly
qDebug() << "Size when opened: " << file.size();
file.close();
}
}
输出:
"sdktool.lnk" , size (unopened): 2817024
Size when opened: 1325
"test.lnk" , size (unopened): 4429312
Size when opened: 951
Windows10的文件属性window显示"test.lnk"大小为951字节,"sdktool.lnk"大小为1325字节
@Rob 的答案在大多数情况下都有效,但是 returns 0 当快捷方式的目标不 exist/is 无效时。
从这种方法中得到启发,您还可以复制快捷方式并更改扩展名。
所以将它全部组合成一个函数(我在这里假设打开目标是 cheaper/safer 而不是复制快捷方式):
qint64 getFileSize(const QString &path)
{
qint64 size = 0;
QFileInfo fileInfo(path);
if(fileInfo.isSymLink() && fileInfo.size() == QFileInfo(fileInfo.symLinkTarget()).size())
{
// Try this approach first
QFile file(path);
if(file.exists() && file.open(QIODevice::ReadOnly))
size = file.size();
file.close();
// If that didn't work, try this
if(size == 0)
{
QString tmpPath = path+".tmp";
for(int i=2; QFileInfo().exists(tmpPath); ++i) // Make sure filename is unique
tmpPath = path+".tmp"+QString::number(i);
if(QFile::copy(path, tmpPath))
{
size = QFileInfo(tmpPath).size();
QFile::remove(tmpPath);
}
}
}
else size = fileInfo.size();
return size;
}