J'ai ce code et il affiche le dossier avec le répertoire lui-même et non son contenu. Je veux afficher son contenu. Je ne veux pas utiliser boost :: système de fichiers.
Comment puis-je résoudre ça?
Code:
#include <windows.h>
#include <iostream>
int main()
{
WIN32_FIND_DATA data;
HANDLE hFind = FindFirstFile("C:\\semester2", &data); // DIRECTORY
if ( hFind != INVALID_HANDLE_VALUE ) {
do {
std::cout << data.cFileName << std::endl;
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
}
Sortie:
semester2
HANDLE hFind = FindFirstFile("C:\\semester2", &data); // DIRECTORY
Vous avez le répertoire parce que c'est ce que vous avez demandé. Si vous voulez les fichiers, demandez-les:
HANDLE hFind = FindFirstFile("C:\\semester2\\*", &data); // FILES
(Vous pouvez plutôt utiliser *.*
si vous préférez, mais apparemment, cela ne fonctionne que pour des raisons de compatibilité ascendante et devrait donc probablement être évité. Voir commentaires et réponse de RbMm.)
Permettez-moi de prendre des notes sur "*.*"
vs "*"
. Ces déclarants ne sont pas égaux.
Deux fichiers différents peuvent exister dans notre dossier: somefile
et somefile.
.
Si nous utilisions l'api de faible niveau ZwQueryDirectoryFile
avec "*.*"
comme expression de recherche (il s'agit du dixième paramètre - FileName [in, optional]
) - nous obtiendrions uniquement somefile.
. Mais si nous utilisions "*"
, nous obtiendrions les deux fichiers - somefile
et somefile.
Si nous essayons FindFirstFile("C:\\semester2\\*.*", &data);
, nous pouvons noter que les deux fichiers somefile
et somefile.
sont renvoyés. Donc, ici "*.*"
vs "*"
ont le même effet - aucune différence d’utilisation.
Pourquoi cela arrive-t-il? Parce que dans FindFirstFileEx
dans kernelbase
(kernel32
), faites une vérification spéciale du masque "*.*"
et si c'est le cas, remplacez-le par ""
(nom vide ayant le même effet que "*"
).
Je pense que cela est fait pour corriger une erreur très courante lorsque les utilisateurs passent "*.*"
au lieu du "*"
correct et pour assurer la compatibilité avec le code hérité.
.
et..
ne font pas réellement partie du répertoire car il est stocké sur disque, mais sont ajoutés par l'API Win32.
Ce n'est pas vrai.
FAT
-, cela est réellement stocké dans le répertoire FAT en tant que 2 première entrée. NTFS
il n'y a pas de telles entrées, mais NTFS.sys
ajoute artificiellement ces 2 entrées si elles sont masquées. Cela se fait donc non pas au niveau de l'API Win32, mais au niveau du noyau - du pilote.
En conclusion, "*.*"
fonctionnera correctement avec l’API Win32 au minimum, mais la méthode correcte et propre consiste à utiliser "*"
ici."*.*"
sera une erreur avec ZwQueryDirectoryFile
api.
La réponse de Harry produira en fait des fichiers et des dossiers ayant une extension dans votre dossier souhaité "C:\\semester2"
.
Ainsi, par exemple, si vous avez un dossier nommé "C:\\semester2\\math.course"
, l'exemple ci-dessus le trouvera également. De plus, si vous avez un fichier nommé "C:\\semester2\\math_scores"
(notez qu'il n'a pas d'extension), il ne sera pas trouvé.
Compte tenu de ce qui précède, je suggérerais la solution suivante:
HANDLE hFind = FindFirstFile("C:\\semester2\\*", &data);
Cela listera la liste complète des éléments dans le répertoire. Le filtrage des répertoires peut être effectué de la manière suivante:
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// directory
}
else
{
// file
}
Les éléments suivants peuvent être utilisés pour les références: Constantes FileAttributes , FIND_DATA struct , API FindFirstFile