IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Free Pascal Discussion :

[Linux] Comment tester un path de façon case insensitive ? [Free Pascal]


Sujet :

Free Pascal

  1. #1
    Membre à l'essai
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 12
    Points
    12
    Par défaut [Linux] Comment tester un path de façon case insensitive ?
    Bonjour à tous,

    Je cale depuis un petit moment sur un problème avec FPC et sollicite votre aide.

    J'ai besoin de pouvoir tester si un fichier (avec son chemin complet) est présent ou pas sur un système Linux mais ceci avec la condition que le test doit être case-insensitive, y compris au niveau du path. Dit autrement , je voudrais que si je cherche à tester l'existence de "/root/test/toto.txt" , les chemins suivants soient considérés comme valides:

    • /root/Test/toto.txt
    • /root/TEST/toto.txt
    • /root/test/Toto.txt


    Merci d'avance pour l'aide ou les pistes que vous pourrez m'apporter.

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    J'ai lu une discussion dans laquelle quelqu'un suggérait de changer la valeur de la constante typée FileNameCaseSensitive. Il faut voir si cela résout votre problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    program SetFileNameCaseSensitive;
     
    { Free Pascal 2.6.4
      Testé sous Windows
    }
     
    begin
      WriteLn(FileNameCaseSensitive); // TRUE
      FileNameCaseSensitive := FALSE;
      WriteLn(FileNameCaseSensitive); // FALSE
      ReadLn;
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    Membre à l'essai
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    Bonjour !

    J'ai lu une discussion dans laquelle quelqu'un suggérait de changer la valeur de la constante typée FileNameCaseSensitive. Il faut voir si cela résout votre problème.
    Merci pour votre réponse.
    J'ai fait le test et fondais beaucoup d'espoir sur cette piste, mais malheureusement FileNameCaseSensitive ne me permet pas de régler le problème. Même en positionnant cette constante à FALSE, j'obtiens le même résultat (les paths avec casse différente ne sont pas trouvés sous Linux).
    Encore merci.

  4. #4
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Pas de quoi ! Apparemment, c'était trop beau pour être vrai. Il doit bien y avoir une façon de faire ce que vous voulez mais, ne connaissant pas Linux, je préfère ne pas trop m'avancer. J'espère que quelqu'un d'autre vous proposera une solution.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  5. #5
    Membre à l'essai
    Homme Profil pro
    ingenieur
    Inscrit en
    Octobre 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2012
    Messages : 22
    Points : 17
    Points
    17
    Par défaut Et avec la directive de compilation {$I+ $I-
    tu test le premier chemin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    {$I-}
    ASSIGN ( FICHIER_TRUC, CHEMIN_UN}
    RESET   (FICHIER_TRUC)
    {$I+}
    IF IORESULT <> 0 THEN
        BEGIN
       Tu test le chemin 2 (idem ci-dessus)
        IF IORESULT <> 0 THEN
              BEGIN
              TU test le chemin 3 (idem dessus}
              END;
        END;
    quand IORESULT = 0 c'est que ca marche

  6. #6
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    @NOVICE76

    Effectivement on peut vérifier l'existence d'un fichier de cette façon mais cela ne résout pas le problème principal, car il faudrait tester toutes les variantes possibles de la chaîne, qui sont innombrables. Les trois exemples donnés par LeMontois n'épuisent pas toutes les possibilités.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  7. #7
    Membre à l'essai
    Homme Profil pro
    ingenieur
    Inscrit en
    Octobre 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2012
    Messages : 22
    Points : 17
    Points
    17
    Par défaut autre solution
    la solution que j'adopte, car j'utilise un grand nombre de programme qui font appel
    à des fichiers , est de gérer l'attribution des noms de chemin à travers une unité
    qui ne fait que cela : la gestion de l'identification des fichiers et des chemins.

    Cette unité est alors appelé par tout programme ayant besoin de ce fichier.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Roland a bien saisi mon problème , mais je vais essayer de le préciser.
    Je récupère des références de fichiers Unix (path + nom de fichier) et j'ai besoin de vérifier si ces fichiers existent ou non sur le système (avec "fileexists" par exemple).
    Or des fois , les fichiers référencés existent bien, mais à la casse près (par exemple je dois considérer comme valide "/root/Test/toto.txt" alors que je cherche "/root/test/toto.txt" ).
    Sous Windows , cette problématique ne se pose pas car le système est case insensitive , mais sous Unix ce n'est pas le cas et donc les deux chemins sont considérés comme différents.

    Encore une fois la piste de Roland avait tout pour plaire , et j'en suis à me demander si cette constante (FileNameCaseSensitive) est vraiment prise en compte .

    Merci encore pour votre aide , je suis convaincu qu'il doit y avoir une solution ...

    Pour info , "FindDiskFileCaseInsensitive" n'a pas réglé mon problème non plus (casse non prise en compte qu'au niveau du nom du fichier, pas du path)

  9. #9
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Bonjour.

    A moins qu'il n'existe une fonction (bien cachée), je ne vois qu'une solution : utiliser TSearchRec avec FindFirst et FindNext.
    C'est d'ailleurs ce que fait la fonction "FindDiskFileCaseInsensitive" : recherche dans un dossier de tous les fichiers, puis comparaison du fichier trouvé et du fichier à trouver en lowercase.

    Pour le path, on pourrait écrire une fonction semblable.
    Pour éviter de parcourir tout ton disque dur , je ferais une recherche de dossier avec la première lettre du nom de celui-ci :
    - d'abord en minuscule ('t*') : si trouvé, comparaison du dossier trouvé avec le dossier à trouver en lowercase.
    - si rien n'est trouvé, deuxième recherche en majuscule ('T*).

    Evidemment, il faut répéter l'opération pour chaque sous-dossier.

    Une fois trouvé le path complet, tu récupères le nom réel du path (avec la casse), puis tu appelles la fonction "FindDiskFileCaseInsensitive".

    Thierry

  10. #10
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 552
    Points : 3 918
    Points
    3 918
    Par défaut
    Salut

    ThWilliam m'a grillé la politesse... J'ai réfléchi à ton problème. Puisqu'il n'existe a priori pas de solution directe à ton problème (sous la forme d'une fonction sympa... mais je ne suis pas allé vérifier dans les bibliothèques), il faut la faire par soi-même avec les outils de base (FindFirst et FindNext) en les combinant dans une routine récursive qui parcourt toute l'arborescence à partir d'un point donné. Pour chaque nom de fichier accédé, il suffit alors de comparer le nom de fichier recherché complet avec celui en cours sans distinction de casse (avec une fonction du style AnsiSameText mais pour l'UTF-8)

    Je te propose d'écrire une routine avec la signature suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    procedure ChercheIgnoreCasse(const RootDir, SubPathName: String; FileNames: TStringList);
    RootDir : le dossier dans lequel il faut rechercher exhaustivement (ici '\root')
    SubPathName: le motif de nom de fichier à retrouver (p.ex. '/Test/toto.txt'), casse quelconque.
    FileNames : liste des noms complets de fichiers trouvés par la routine (oaramètre de sortie).
    Pas le temps de proposer le code complet pour le moment.

    Le fait d'utiliser une TStringList permettra de savoir s'il y a 0, 1 ou plusieurs fichiers trouvés (propriété count), peut-être que la présence de plusieurs est une erreur. Dans Windows, le problème n'a pas lieu mais sous Linux... Ce qui peut compliquer l'exploitation, ne te serait-il pas possible de normaliser le nom de fichier sous Linux ? Le problème devient alors trivial.

    Attention, il ne faudra pas négliger les droits d'accès, ton fichier est copié dans \root, selon le compte sous lequel est lancé le programme (si ce n'est pas root), certains fichiers ne pourront être accédés (en recherche) ou ouverts (selon les droits des répertoires et des fichiers).

    Enfin, écrire la routine (code + appelant) de façon portable si ton programme est voué à tourner sous plusieurs systèmes. A toutes fins utiles : http://wiki.freepascal.org/Multiplatform_Programming_Guide/fr

    Cette réponse manque de détail car je fais cela sur ma pause déjeuner.

    @+

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  11. #11
    Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Août 2012
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 18
    Points : 53
    Points
    53
    Par défaut
    Bonjour,

    Donc, effectivement, j'étais partis sur un proposition similaire.
    Ou parse tes dossiers pour comparer en Uppercase.
    Et créer ainsi plusieurs route possible, et les explorer.
    En sachant que l'ensemble de recherche est correspond à ta route d'origine.

    Ou sinon comme tu es sur Linux.
    Tu dois pouvoir faire un Regex en ligne de commande.
    grep ‘[a-zA-Z>’ filename


    cldt
    Iwoks.

  12. #12
    Membre à l'essai
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Merci à tous pour vos pistes.
    Je vais faire des essais et si possible des tests de performance .
    Je posterai ici les résultats.

    @+

  13. #13
    Membre à l'essai
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2013
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Un peu de FindAllFiles , TstringList et UPPERCASE et l'affaire est dans le sac
    Encore un grand merci à tous pour vos réponses .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    program RechercheFileNameCaseSensitive;
    { Recherche fichier sous Unix en Case Insensitive}
    uses
    FileUtil,Classes,sysutils;
     
    var
    QUOI,DIRSELECT : string; 
    fichiers : TStringList;
    i : integer;
     
    begin
    DIRSELECT:='/root/';
    QUOI:='/root/test/toto.txt';
     
    fichiers := FindAllFiles(DIRSELECT, '*.txt', true); //recherche des fichiers textes
     
    writeln(Format('Trouvé %d fichiers textes',[fichiers.Count]));
     
    for i:= 0 to fichiers.count -1 do 
    		if uppercase(fichiers.ValueFromIndex[i]) = uppercase(QUOI) then  
    				begin 
    				writeln(QUOI + ' trouvé dans ' +fichiers.ValueFromIndex[i]);
    				break;
    				end;
     
    fichiers.free;
    end.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # ./testfic
    Trouvé 228 fichiers textes
    /root/test/toto.txt trouvé dans /root/Test/Toto.txt
    #

  14. #14
    Membre chevronné

    Homme Profil pro
    au repos
    Inscrit en
    Février 2014
    Messages
    429
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : au repos

    Informations forums :
    Inscription : Février 2014
    Messages : 429
    Points : 1 884
    Points
    1 884
    Par défaut
    Et bien, j'ai appris l'existence de la fonction " FindAllFiles ".
    Donc merci à toi.

    Thierry

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. comment tester si une case d'un tableau est vide
    Par khadi8 dans le forum Débuter
    Réponses: 7
    Dernier message: 01/05/2013, 09h13
  2. Comment tester le watchdog Linux ?
    Par petitclem dans le forum Linux
    Réponses: 0
    Dernier message: 27/01/2011, 17h53
  3. comment tester si une case est cochée dans un fenêtre d'impression
    Par tibofo dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 24/08/2009, 16h13
  4. Comment tester si un repertoire est vide sous Linux
    Par chouchouappc dans le forum Linux
    Réponses: 3
    Dernier message: 24/02/2005, 12h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo