Scandisc simple pour lister le contenu d'un repertoire (+ des sous-repertoires....)

Soyez le premier à donner votre avis sur cette source.

Vue 9 663 fois - Téléchargée 668 fois

Description

Bin voila, je pense que tout est dans le titre. C'est un petit programme qui scanne un repertoire et qui ecrit le contenu dans un fichier texte. On peut scanner un disque entier en demandant de scanner le repertoire 'C://'

Chez moi, il met environs 30 secondes pour scanner les 110.000 fichiers de mon disque dur. Je ne sais pas pourquoi... la vitesse est tres tres variable. Je pense qu'il doit garder des informations en mémoire (des fois il met 2sc :)

Ah oui, je l'ai fait avec Visual C++ 5, mais il doit pouvoir tourner assez facilement avec d'autres compilateurs je pense...

Source / Exemple :


#include <windows.h>
#include <stdio.h>
#include <conio.h> 

void Save_En_Tete_Fichier(FILE* f, char *Chemin);																  
void ScanContenuDossiers(char *CurrentDir, FILE* f);

char Indentation[256] = ""; // sert à indenter dans le fichier texte

int main()
{
	FILE *f;
	char Dir_File[_MAX_PATH];
	char Chemin[_MAX_DIR];

	printf("\n\nTaper l'adresse du repertoire a scanner:\n\n");
	printf("par exemple : \"C://WINNT/\"");
	printf("\n\nChemin: ");
	gets(Chemin);

	printf("\n\nTaper le nom du fichier dans lequel sera enregistre les informations :\n\n");
	printf("\n\nChemin: ");
	gets(Dir_File);

	f = fopen(Dir_File,"wt");
	if (f == NULL)
	{
		printf("Erreur lors de l'ouverture du fichier");
		return 0;
	}
	else
	{
		Save_En_Tete_Fichier(f, Chemin);

		printf("Veuillez Patienter ...\n");

		ScanContenuDossiers(Chemin, f);					

		fclose(f);

		printf("Operation reussie !\n");
	}

	return 0;
}

void Save_En_Tete_Fichier(FILE* f, char *Chemin)
{
	////////////////////////////////////////////////////////////////////////////////////////////////
	char *Texte;
	
	// on alloue de la memoire pour enregistrer deja les informations qui sont en en-tete du fichier
	Texte = (char*) malloc((90+strlen(Chemin))*sizeof(char)+1);
		// le +1 sert pour le '\0' à la fin de la chaine car strlen() ne le compte pas.
		// l'ensemble du texte ecrit en dessous fait 90 caracteres (zavez cas compter ;)
	
	// on copie l'en-tete dans Texte
	strcpy(Texte, "Repertoire en cours : ");
	strcat(Texte, Chemin);
	strcat(Texte, "\n");
	strcat(Texte, "--------------------------------------");
	strcat(Texte, "\n\n");
	strcat(Texte, "Fichiers présents : \n\n");

	// on enregistre les données dans notre fichier
	fwrite(Texte, sizeof(char), strlen(Texte), f);

	// on libère la mémoire
	free(Texte);
	////////////////////////////////////////////////////////////////////////////////////////////////
}
void ScanContenuDossiers(char *CurrentDir, FILE *f)
{
	/* ATTENTION, ICI IL FAUT EVITER D'UTILISER DES FONCTIONS COMME STRCPY OU STRCAT QUI RALLENTISSENT ENORMENENT" */
	/* ESSAYEZ DE RAJOUTER UN STRCPY DANS LA BOUCLE DO... LE TEMPS D'EXECUTION VA CONSIDERABLEMENT AUGMENTER */ 

	char Chemin[MAX_PATH];
	WIN32_FIND_DATA wData;
	HANDLE listing;

	// on rajoute *.* à la fin de l'adresse pour FindFirstFile() 
	sprintf (Chemin, "%s*.*", CurrentDir);
	listing = FindFirstFile(Chemin, &wData);
	
	// on enleve le *.* à la fin de l'adresse
	sprintf (Chemin, "%s", CurrentDir);

	if (listing != INVALID_HANDLE_VALUE)
	{
		do
		{
			if ((strcmp(wData.cFileName, ".."))&&((strcmp(wData.cFileName, "."))))
			{
				if (wData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				{
					// puisque c'est un repertoire, on recupere la nouvelle adresse, et on va rentrer dedans...
					sprintf(Chemin, "%s%s/", CurrentDir, wData.cFileName);
					// avant, on stoque le nom du repertoire dans notre "fichier de listing" (fichier créé par notre programme)
					fprintf(f, "%s+ %s\n", Indentation,wData.cFileName);
					// on indente (car on va rentrer dans un repertoire)
					strcat(Indentation, " |  ");
					// on rappelle la fonction pour qu'elle s'execute dans le repertoire (recurence)
					ScanContenuDossiers(Chemin, f);
					// on enleve l'indentation puisque on ressort du repertoire
					Indentation[strlen(Indentation)-4] = '\0';
							
					// reviens un repertoire en arrière
					int j = strlen(Chemin)-2;
					while (j>0)
					{
						if (Chemin[j] == '/')
						{
							Chemin[j+1] = '\0';
							break;
						}
						j--;
					}
				}
				else // si c'est pas un dossier, c'est un fichier...

					fprintf(f, "%s- %s\n", Indentation,wData.cFileName); // on enregistre le nom du fichier
			
			}
		}while (FindNextFile(listing, &wData));
	}
	FindClose(listing);
}

Conclusion :


Petit coucou à Jcdjcd qui a aussi fait un programme similaire mais qui ne l'a pas mis pour le moment sur le site.

remis à jour le 21 avril 2004 :
- un tout petit peu plus rapide qu'avant...
- avant je ne regardais pas ce que retournait FindFirstFile() <- ne renvoi pas tjours '.' ou '..'
- racourci un peu le source (c'etait redondent à un endroit)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

informatique02
Messages postés
8
Date d'inscription
jeudi 31 janvier 2008
Statut
Membre
Dernière intervention
8 juin 2008
-
mais comment le modifier pour qu'il marche en langage c sur linux???
cs_bloom1
Messages postés
328
Date d'inscription
jeudi 26 août 2004
Statut
Membre
Dernière intervention
8 mars 2007
-
Oui j'ai même modifié la source pour faire un dictionnaire de tous mes fichiers, et je vais probablement utiliser cette source pour faire un projet.
Merci !
mikovitch1
Messages postés
2
Date d'inscription
jeudi 13 février 2003
Statut
Membre
Dernière intervention
14 février 2005
-
tres tres bon!
marche nikel
tres bien commenté!
vinc1008881
Messages postés
257
Date d'inscription
dimanche 22 août 2004
Statut
Membre
Dernière intervention
29 septembre 2010
-
exelent tout simplement !
thesnakeplisken
Messages postés
4
Date d'inscription
mercredi 5 février 2003
Statut
Membre
Dernière intervention
4 mai 2004
-
Salut à tous. Bravo et merci il est super ce code. Je débute en c++ et je me suis permis de modifier ton code. J'ai remis les anti-slash car je compte utiliser ce source pour lancer des fichiers et je sais pas si tous les programmes apprécieront les slash et j'ai enlevé la fonction pour écrire dans le fichier (j'ai rédirigé vers la console) car je compte intégrer les résultats dans une liste virtuelle afin de leur faire subir un classement dès que j'aurai etoffé mes connaissances.

#include <windows.h>
#include <stdio.h>
#include <conio.h>

void ScanContenuDossiers(char *CurrentDir);

int main()
{
char Dir_File[_MAX_PATH];
char Chemin[_MAX_DIR];

printf("\n\nTaper l'adresse du repertoire a scanner:\n\n");
printf("par exemple : "C://WINNT/"");
printf("\n\nChemin: ");
gets(Chemin);


printf("Veuillez Patienter ...\n");
ScanContenuDossiers(Chemin);
printf("Operation reussie !\n");

return 0;
}

void ScanContenuDossiers(char *CurrentDir)
{
/* ATTENTION, ICI IL FAUT EVITER D'UTILISER DES FONCTIONS COMME STRCPY OU STRCAT QUI RALLENTISSENT ENORMENENT" */
/* ESSAYEZ DE RAJOUTER UN STRCPY DANS LA BOUCLE do... LE TEMPS D'EXECUTION VA CONSIDERABLEMENT AUGMENTER */

char Chemin[MAX_PATH];
WIN32_FIND_DATA wData;
HANDLE listing;

// on rajoute *.* à la fin de l'adresse pour FindFirstFile()
sprintf (Chemin, "%s*.*", CurrentDir);
listing = FindFirstFile(Chemin, &wData);

// on enleve le *.* à la fin de l'adresse
sprintf (Chemin, "%s", CurrentDir);

if (listing != INVALID_HANDLE_VALUE)
{
do
{
if ((strcmp(wData.cFileName, ".."))&&((strcmp(wData.cFileName, "."))))
{
if (wData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// puisque c'est un repertoire, on recupere la nouvelle adresse, et on va rentrer dedans...
sprintf(Chemin, "%s%s\", CurrentDir, wData.cFileName);
// on rappelle la fonction pour qu'elle s'execute dans le repertoire (recurence)
ScanContenuDossiers(Chemin);
// reviens un repertoire en arrière
int j = strlen(Chemin)-2;
while (j>0)
{
if (Chemin[j] == '\\')
{
Chemin[j+1] = '\0';
break;
}
j--;
}
}
else // si c'est pas un dossier, c'est un fichier...

printf("%s%s\n",Chemin,wData.cFileName); // on affiche le nom du fichier

}
}while (FindNextFile(listing, &wData));
}
FindClose(listing);
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.