diff --git a/src/dfm-io/dfm-io/denumerator.cpp b/src/dfm-io/dfm-io/denumerator.cpp index 48dafe8..8c6d40a 100644 --- a/src/dfm-io/dfm-io/denumerator.cpp +++ b/src/dfm-io/dfm-io/denumerator.cpp @@ -446,9 +446,13 @@ char *DEnumeratorPrivate::filePath(const QUrl &url) QUrl DEnumeratorPrivate::buildUrl(const QUrl &url, const char *fileName) { - auto path = url.path() == "/" ? - "/" + QString(fileName) : - url.path() + "/" + QString(fileName); + QString path; + if (url.path() == "/") { + path = "/" + QString(fileName); + } else { + QString dirPath = url.path(); + path = dirPath.endsWith('/') ? dirPath + QString(fileName) : dirPath + "/" + QString(fileName); + } QUrl nextUrl = QUrl::fromLocalFile(path); if (url.userInfo().startsWith("originPath::")) { @@ -674,34 +678,19 @@ bool DEnumerator::hasNext() const while (!d->stackEnumerator.isEmpty()) { GFileEnumerator *enumerator = d->stackEnumerator.top(); - GFileInfo *gfileInfo = nullptr; - GFile *gfile = nullptr; g_autoptr(GError) gerror = nullptr; d->checkAndResetCancel(); - bool hasNext = g_file_enumerator_iterate(enumerator, &gfileInfo, &gfile, d->cancellable, &gerror); + // Use g_file_enumerator_next_file() which returns a GFileInfo* for the next + // entry (or NULL). This avoids ambiguous iterate() behavior across backends. + GFileInfo *nextInfo = g_file_enumerator_next_file(enumerator, d->cancellable, &gerror); + if (nextInfo) { + d->nextUrl = d->buildUrl(d->uri, g_file_info_get_name(nextInfo)); + d->dfileInfoNext = DLocalHelper::createFileInfoByUri(d->nextUrl, g_file_info_dup(nextInfo), FILE_DEFAULT_ATTRIBUTES, + d->enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks); - if (hasNext) { - if (!gfileInfo || !gfile) { - // 当前枚举器已完成,弹出并继续下一个 - GFileEnumerator *enumeratorPop = d->stackEnumerator.pop(); - g_object_unref(enumeratorPop); - continue; - } - g_autofree gchar *path = g_file_get_path(gfile); - if (path) { - d->nextUrl = QUrl::fromLocalFile(QString::fromLocal8Bit(path)); - if (DFMUtils::isInvalidCodecByPath(path)) - d->nextUrl.setUserInfo(QString::fromLatin1("originPath::") + QString::fromLatin1(path)); - } else { - g_autofree gchar *uri = g_file_get_uri(gfile); - d->nextUrl = QUrl(QString::fromLocal8Bit(uri)); - if (DFMUtils::isInvalidCodecByPath(uri)) - d->nextUrl.setUserInfo(QString::fromLatin1("originPath::") + QString::fromLatin1(path)); - } - d->dfileInfoNext = DLocalHelper::createFileInfoByUri(d->nextUrl, g_file_info_dup(gfileInfo), FILE_DEFAULT_ATTRIBUTES, - d->enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks); + g_object_unref(nextInfo); // 如果是目录且需要遍历子目录 if (d->enumSubDir && d->dfileInfoNext && d->dfileInfoNext->attribute(DFileInfo::AttributeID::kStandardIsDir).toBool()) { @@ -720,9 +709,12 @@ bool DEnumerator::hasNext() const return true; } + // nextInfo == NULL: either finished or an error occurred if (gerror) { d->setErrorFromGError(gerror); - return false; + d->nextUrl = QUrl(); + d->dfileInfoNext.reset(); + return true; } // 当前枚举器已完成,弹出并继续下一个