VÉRIFIER L'EXISTENCE D'UN FICHIER (SOUS WINDOWS(32/64) EXCLUSIVEMENT !!! C'EST P

foxugly Messages postés 13 Date d'inscription jeudi 29 mai 2003 Statut Membre Dernière intervention 14 octobre 2004 - 31 juil. 2004 à 06:03
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011 - 4 janv. 2007 à 15:02
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/9263-verifier-l-existence-d-un-fichier-sous-windows-32-64-exclusivement-c-est-pas-portable-sous-d-autres-os

magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
4 janv. 2007 à 15:02
si on devait faire une nouvelle fonction pour chaque extension, on aurais pas fini de coder...

on a déjà répondu à la question ici en détaillant différentes méthodes, leurs avantages & inconvénients.

Bonne prog à tous
et que vos voeux se réalisent pr cette nouvelle année.
Magicalement
Nono.
chadilou Messages postés 1 Date d'inscription mardi 2 janvier 2007 Statut Membre Dernière intervention 2 janvier 2007
2 janv. 2007 à 03:16
svp j'aimerais savoir comment verifier l'existance d'un fichier .txt en c++
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
11 nov. 2006 à 02:03
ca m'érite une mise à jour, merci pour la remarque
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 nov. 2006 à 01:58
return (0 <= (INT_PTR) GetFileAttributes( fname ) );
évite les constantes ce qui permet portabilité vers x64.
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
11 nov. 2006 à 01:50
la raison que tu invoques est ridicule ... si on veut savoir si on peut ouvrir un fichier pour le lire on fait pas un « fileExists() » dessus, on l'ouvre en « mode lecture » et puis on test ensuite, mon exemple c'est simplement pour tester l'existance d'un fichier, pour savoir si le fichier X existe ou non, pas pour savoir si on peut le lire, écrire dedans, etc. d'où le nom de la fonction :: fileExists()

*** hors sujet ***

pour ton histoire de portabilité, c'est évident que d'utiliser des librairies déjà développés/testés/etc. ca aide beaucoup mais ca n'empêche pas qu'on puisse quand même ajouter du code spécifique à un OS quelconque, regardes les softs(portables) open source, il y en a beaucoup qui le font, ils ne se basent pas toujours sur des librairies telles que qt/gtk/wx/etc. pour développer leurs softs(fonctionnalités spécifiques, ...), ils ont aussi des parties spécifiques à des OS X, Y et Z ... alors oui, les librairies du genre à qt/gtk/wx/etc. sont utiles mais elles ne contiennent pas toujours tout ce qu'il faut pour développer nos applications(et là je parle pas d'une simple calculatrice hein ...), surtout quand on veut quelque chose de performant, ce genre de librairie n'est pas souvent adapté pour ca ...

c'est un peu comme les distro. linux, les builds x86 qui ne sont pas optimisés pour chaque PC(intel et compatible) mais c'est plutôt un build générique, les librairies telles que qt/... c'est pas mal la même chose ...

en passant, la portabilité d'un OS à un autre n'est pas une « obligation », loin de là, pour un développeur qui développe uniquement sous Windows(comme moi) par exemple, ca lui servirait à quoi? moi personnellement j'en vois pas l'interet et j'en ai pas besoin même si, oui oui, j'ai Linux sur deux de mes postes ...

*** hors sujet ***

il faudrait aussi penser à regarder le titre de l'exemple ... à moins d'avis contraires, j'ai bien mis « WIN » dans le titre, non? et on voit aussi « #include <windows.h> dans le code je crois, mais je suis pas certain, faudrait vérifier :-/
j'ai aussi mis « Linux » ou « Portable » ou autre dans le titre/code/... ??? quelqu'un pourrait confirmer s'il vous plait?

_
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
9 nov. 2006 à 22:08
turneron >> Brunews a raison. Il n'a pas dit que le C/C++ n'est pas portable. Toi aussi tu as raison. Mais ce que veux dire BruNews c'est que la portabilité se fait toujours au détriment de la qualité de l'application. On a certes un programme qui tournera sur toutes les plateformes, mais ce sera moins bien que s'il était conçu pour une seule plateforme. Chaque OS a ses propres spécificités. Les librairies assurant la compatibilité empêchent le programme de communiquer directement avec le système d'où la perte de performance. Cela empêche également le codeur de bien comprendre le fonctionnement du système. La compréhension du fonctionnement du système permet de bien optimiser le code et mieux maitriser le comportement de l'application.
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
9 nov. 2006 à 19:06
BruNews -> 50 fois qu'on répète qu'un fichier peut etre ouvert en exclusif avant par un autre processus, auquel cas ton truc répond nimporte quoi.
On ne traite jamais l'existence par l'ouverture, peut tres bien exister mais ne pas etre dispo.

--> Oui mais si tu teste l'existance d'un fichier, en général c'est au moins pour le lire, or si ma méthode renvoie faux c'est que tu n'a pas acces au fichier. Si le fichier existe mais qu'il est ouvert de facon exclusive par un autre processus, et que ma fonction renvoyée 'true' tu croirais que tu peux l'ouvrir pour lire dedans or cela ferait certainement une "seg fault" lorsque tu essayerais.


BruNews -> Si on ne devait faire que du portable, on serait encore en console (et encore), évitez donc ces ritournelles stériles. On dev au mieux pour chaque systeme cible et là on a une chance de faire un truc performant, pas une daube pour tous.

--> C'est totalement faux, le C/C++ est portable, c'est à dire qu'un même code est censé compiler et avoir le même comportement sous n'importe quelle plateforme (ce qui est le cas, y'a pas que visual dans la vie !!!). Quand à faire une interface graphique, y'a QT et wxwidget pour ne citer qu'eux qui te permettent d'avoir une belle interface graphique portable. Heureusement que tu n'a pas écrit VLC (par exemple) car à t'écouter tu aurait réécrit l'intégalité du code pour le porter sous Linux / Mac et autres ...

Tout (BON) code devrait (doit) pouvoir compiler indéferemment de la plateforme.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
9 nov. 2006 à 18:10
50 fois qu'on répète qu'un fichier peut etre ouvert en exclusif avant par un autre processus, auquel cas ton truc répond nimporte quoi.
On ne traite jamais l'existence par l'ouverture, peut tres bien exister mais ne pas etre dispo.

Si on ne devait faire que du portable, on serait encore en console (et encore), évitez donc ces ritournelles stériles. On dev au mieux ^pour chaque systeme cible et là on a une chance de faire un truc performant, pas une daube pour tous.
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
9 nov. 2006 à 15:00
Mon avis sur quoi ?
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
9 nov. 2006 à 14:43
ouvre ce même fichier en écriture en parallele...
et lance ton test.

ton avis turnerom?
turnerom Messages postés 492 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 12 janvier 2012 1
9 nov. 2006 à 10:48
Non mais sérieux quoi, voici comment tester l'existance d'un fichier de manière simple et portable en C++:

#include
#include <fstream>

using namespace std;

bool exist(const string file_name)
{
ifstream file(file_name.c_str(), ios::in);

if (!file) return false;

file.close();
return true;
}
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
15 avril 2005 à 18:31
non, CT pas sérieux, en plus j'ai fait ça il y a lgt,
il y a un moyen de connaitre l'arbo et les attrb des fichiers sans les ouvrir

faudra retrouver ça...
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
15 avril 2005 à 18:04
a ui, et idem pr les histoire de droits....
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
15 avril 2005 à 16:03
ben faudrait voir avec un expert unix si on peut ouvrir un fichier en mode exclusif parce que si oui (comme sous Windows) on ne teste pas la présence d'un fichier par le fait qu'on puisse l'ouvrir. Pourrait répondre non alors que le fichier existe bien.
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
15 avril 2005 à 15:55
oubliez les " /// Algo : TODO" du code précédent,
j'avais oublié de décoché l'option dans MétaProg et ai posté sans relire une derniere fois

dslé
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
15 avril 2005 à 15:45
//Si l'on veut la mm chose fonctionnant sur les différents systemes, seriez vous d'accord avec ceci:



bool __stdcall BFichier::existe(const char * nomFic)
{
/// -------------------------------------------------------------------------------
/// ---------------- BFichier::existe(const char* nomFic) -> bool ----------------
/// -------------------------------------------------------------------------------
/// ----- Objectif : verifier si le fichier existe
/// ----- PreCond : nomFic!="" && nomFic!=NULL
/// ----- PostCond : /
/// -------------------------------------------------------------------------------
/// ----- const char* nomFic : nom du fichier
/// ---------------------------------------------------------------------------------
/// ----- retour (bool) : existance fichier
/// -------------------------------------------------------------------------------
/// ----- Var Muettes (cf.partie préc) (1) : nomFic
/// ----- Var Internes à la fonction (2) : existe ,fichier
/// ----- Var In (1) : nomFic

#ifdef BUNIX
bool existe=false;
FILE*fichier=fopen(nomFic,"r");
existe=(NULL!=fichier);
/// Algo : SI TODO
if(existe)
/// Algo : TODO
fclose(fichier);
return existe;

#else /* BUNIX */

return( 0xffffffffu != GetFileAttributes( nomFic ) );
/* équivalent
FileExists@4 PROC NEAR ; _fname$ = eax
push eax
call DWORD PTR __imp__GetFileAttributesA@4
xor ecx, ecx
test eax, eax
setge cl
mov eax, ecx
ret 0
_FileExists@4 ENDP
*/
#endif /* BUNIX */

}


//(cette fonction étant en static dans une classe de lib)
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
15 avril 2005 à 08:59
merci bcp BruNews pr ces lumieres...
C'est sans appel....

Nono.

NitRic> tu vois, il ne faut js désespérer, des choses ressortent parfois de cette <cathédrale Del Bazard> ;)
NitRic Messages postés 402 Date d'inscription mardi 1 mai 2001 Statut Membre Dernière intervention 15 août 2011
15 avril 2005 à 03:59
4 ans pour obtenir des commentaires sur mon exemple, et bien =P

Merci pour toutes ces précisions(commentaires) :}



~(.:: NitRic ::.)~
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
14 avril 2005 à 18:36
Excusez petite erreur d'inattention, avec GetFileAttributes c'es 2 Ko que fait exe et non 2.5.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
14 avril 2005 à 18:32
Portabilité ??? évacuons de suite, c'est spécialisé Windows, sera portable sur Windows et basta.

Il est clair que si tu utilises des couches d'interprétation, ce ne sera jamais aussi direct que l'appel direct API, ni en taille de code ni en vitesse.
Pour ne rien masquer, faisons exemple en sautant le CRT:

#include <windows.h>

int __stdcall FileExists(char *fname)
{
return (GetFileAttributes(fname) != 0xFFFFFFFF);
}

// ceci sert aux 3 essais

#pragma comment(linker, "/entry:myWinMain")
int WINAPI myWinMain()
{
MessageBox(0, FileExists("C:\\truc.txt") ? "OUI": "NON", "A", 0);
ExitProcess(0);
}

Exe fait 2.5 Ko, semble optimal en taille.
ASM résultant:
_FileExists@4 PROC NEAR ; _fname$ = eax
push eax
call DWORD PTR __imp__GetFileAttributesA@4
xor ecx, ecx
cmp eax, -1
setne cl
mov eax, ecx
ret 0
_FileExists@4 ENDP
C'est impec et aucun param, à noter (comme les 2 autres qui vont suivre) que le compilo va 'inliner' tout cela.
2eme essai, on peut forcer la suppression de la constante -1 en faisant le 'TEST' seulement sur EAX, devrait gagner 1 octet (pas le temps de mesurer).
int __stdcall FileExists(char *fname)
{
return (0 <= (long) GetFileAttributes(fname));
}
Exe même taille, 'TEST' seul sur EAX:
_FileExists@4 PROC NEAR ; _fname$ = eax
push eax
call DWORD PTR __imp__GetFileAttributesA@4
xor ecx, ecx
test eax, eax
setge cl
mov eax, ecx
ret 0
_FileExists@4 ENDP

3eme essai, les choses se gâtent:
#include // devient obligatoire

int __stdcall FileExists(char *fname)
{
return (_access(fname, 0) != -1);
}

ASM résultant:
_FileExists@4 PROC NEAR ; _fname$ = eax
push 0
push eax
call __access
xor ecx, ecx
add esp, 8
cmp eax, -1
setne cl
mov eax, ecx
ret 0
_FileExists@4 ENDP

Exe fait 7 Ko !!! la fonction a 2 PUSH au lieu de 1 et une remontée de ESP, voila qui occupera nos processeurs.
Il est aussi à noter que _access appelle GetFileAttributes en interne, vérifiable en regardant les dépendances de l'EXE grace à la suppression du CRT.
Résultat des courses, si on écrit pour Windows on ne met rien entre lui et nous et on est gagnant à tout coup.

ciao...
magic_Nono Messages postés 1878 Date d'inscription jeudi 16 octobre 2003 Statut Membre Dernière intervention 16 mars 2011
14 avril 2005 à 16:40
quelle différence avec

bool BFichier::existe(const char * nomFic)
{
return _access(nomFic,0)!=-1;
}

??

portabilité, rapidité??

++
Nono.
foxugly Messages postés 13 Date d'inscription jeudi 29 mai 2003 Statut Membre Dernière intervention 14 octobre 2004
31 juil. 2004 à 06:03
ya pas une fonction dans l'API qui fait ça ?
Rejoignez-nous