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

Langage Perl Discussion :

fonction opendir suivie de traitement


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut fonction opendir suivie de traitement
    Bonjour,
    Je cherche à appliquer un programme à tous les fichiers d'un même dossier. En lisant les discussions du forum(cf petitange_lili, boucle analyser tous les fichiers d'un répertoire), j'ai vu qu'il existait la fonction opendir/readdir/closedir. Malheureusement quand je l'intègre à mon programme, l'ouverture des fichiers m'est interdite.
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    my $dossier = "mars";
    opendir (DIR, $dossier) or die "$dossier n'existe pas !";
    my @files = readdir DIR;
    foreach my $nom_fichier_source (@files){
     
        # Ci-dessous les lignes utilisees dans le programme de base
        # pour traiter les fichiers un a un :
        #print "Donnez le nom du fichier :\n";
        #my $nom_fichier_source = <STDIN>;
        #chomp($nom_fichier_source);
     
    my $nom_tronque = $nom_fichier_source;
    $nom_tronque =~ s/\.log//;
    my $nom_fichier_resultat = "$nom_tronque"."_resultat_sauv.txt";
     
    open my ($source), '<', $nom_fichier_source 
      or die "Impossible d'ouvrir votre fichier $nom_fichier_source : $!\n ";
    open my ($destination), '>', $nom_fichier_resultat
      or die "Impossible d'ouvrir votre fichier $nom_fichier_resultat : $!\n ";
     
    print $destination "Etablissement\tNb total fich\tNb fich modif\n";
     
    # "variables d'état"
    my ($etab, $total_fic, $fic_modif) = (undef,  "0\t", "0");
    my $compteur = 0;
     
    while (my $ligne=<$source>){
      # mon programme à proprement parler
    }
     
    close $source;
    close $destination;
    }
    closedir DIR;

    Par ailleurs, pour comprendre la fonction, j'ai testé le programme proposé en FAQ "Handle de répertoire". Mais ce programme me rend le résultat 0 fichiers, 2 répertoires, alors qu'il devrait répondre 20 fichiers (documents texte, .log) et 0 répretoires.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/perl
    $nbrep = 0;
    $nbfic = 0;
    $dossier = "mars";
    opendir DIR, $dossier or die "$dossier n'existe pas !";
    @files = readdir DIR;
    foreach $fichier (@files) {
    if (-f $fichier) { $nbfic++; }
    elsif (-d $fichier) { $nbrep++; }
    }
    close DIR;
    print "Il y a $nbfic fichier(s) et $nbrep répertoire(s) dans $dossier.\n";
    Merci pour vos conseils.

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par apprenti doc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    open my ($source), '<', $nom_fichier_source 
      or die "Impossible d'ouvrir votre fichier $nom_fichier_source : $!\n ";
    Une erreur extrêmement courante : Ce n'est pas parce que vous avez ouvert le dossier avec opendir() que vous êtes dans ce dossier... Autrement dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    open my ($source), '<', "$dossier/$nom_fichier_source" 
      or die "Impossible d'ouvrir votre fichier $nom_fichier_source : $!\n ";
    marchera mieux...

    Citation Envoyé par apprenti doc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/perl
    $nbrep = 0;
    $nbfic = 0;
    $dossier = "mars";
    opendir DIR, $dossier or die "$dossier n'existe pas !";
    @files = readdir DIR;
    foreach $fichier (@files) {
    if (-f $fichier) { $nbfic++; }
    elsif (-d $fichier) { $nbrep++; }
    }
    close DIR;
    print "Il y a $nbfic fichier(s) et $nbrep répertoire(s) dans $dossier.\n";
    Merci pour vos conseils.
    Même remarque :
    Merci de nous avoir signalé cette erreur, nous allons la corriger au plus vite. (et le close() à la place du closedir() aussi)

    Par ailleurs, par souci de cohérence autant que d'esthétique (et un peu de sécurité, encore que les probabilités de collision soient des plus faibles), pourquoi ne pas adopter pour opendir comme pour vos open des handles lexicaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    opendir my($dir), $dossier or die "$dossier n'existe pas !";
    $dir s'autofermera quand il n'y aura plus de référence vers lui.

    --
    Jedaï

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jedai
    $dir s'autofermera quand il n'y aura plus de référence vers lui.
    --
    Jedaï
    Cela veut donc dire que je n'ai pas besoin du closedir $dir (?)...

    J'ai intégré tes corrections mais, si ça fonctionne bien pour l'exemple de la FAQ, en revanche pour mon programme, ça ne marche pas mieux .
    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
    my $dossier = "mars";
    opendir my($dir), $dossier or die "$dossier n'existe pas !";
    my @files = readdir $dir;
    foreach my $nom_fichier_source (@files){
     
    #print "Donnez le nom du fichier :\n";
    #my $nom_fichier_source = <STDIN>;
    #chomp($nom_fichier_source);
    my $nom_tronque = $nom_fichier_source;
    $nom_tronque =~ s/\.log//;
    my $nom_fichier_resultat = "$nom_tronque"."_resultat_sauv.txt";
     
    open my($source), '<', "$dossier/$nom_fichier_source"  
      or die "Impossible d'ouvrir votre fichier $nom_fichier_source : $!\n ";
    open my($destination), '>', $nom_fichier_resultat
      or die "Impossible d'ouvrir votre fichier $nom_fichier_resultat : $!\n ";
    En fait, je suis incapable d'indiquer un chemin d'accès à un fichier. Je mets toujours le programme à côté des fichiers source pour contourner le problème mais là ça ne convient pas ! Comme je travaille ici avec windows, j'ai essayé de transformer le / en \, mais rien à faire ; ça change l'indication d'erreur mais c'est tout ! C'est sûrement tout bête !...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open my($source), '<', "$dossier\$nom_fichier_source"

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Et ça ça marche ?
    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
    my $dossier = "mars";
    opendir my($dir), $dossier 
      or die "$dossier n'existe pas !";
     
    while( my $nom_source = readdir $dir ) {
     
      next if $nom_source =~ m/^\.\.?$/; # pseudo-dossiers . et ..
     
      if ( (my $nom_resultat = $nom_source) =~ s/\.log$/_resultat_sauv.txt/ ) {
     
        open my($source), '<', "$dossier/$nom_source"  
          or die "Impossible d'ouvrir votre fichier $nom_source : $!\n ";
        open my($destination), '>', "$dossier/$nom_resultat"
          or die "Impossible d'ouvrir votre fichier $nom_resultat : $!\n ";
     
        # suite du traitement
      }
    }
    "$dossier/$fichier" marche sous Windows (du moins sous les NT, 2000 et XP et très probablement Vista) et sous Linux/Unix/BSD/MacOSX/... (pas VMS probablement et pas Mac Classic), tu lances bien ton script à partir du répertoire dans lequel se trouve le dossier "mars" ?

    --
    Jedaï

  5. #5
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par apprenti doc
    Cela veut donc dire que je n'ai pas besoin du closedir $dir (?)...
    En fait le handle meurt (et donc se ferme) dès lors que plus rien ne pointe vers lui, comme pour n'importe quelle valeur, mais avec les handles GLOB, la variable est globale, et persiste donc tant qu'on ne la détruit pas explicitement (le handle n'est donc détruit que dans trois cas : si on détruit la variable explicitement (rare), si on utilise un close()/closedir() dessus (si c'est un programme écrit correctement) ou à la fin de l'exécution (ce qui est dramatique si le programme est du genre à s'exécuter longtemps...) ). Avec une variable lexicale, toute référence sur le handle disparaît dès la fin de la portée de la variable sauf si on transmet explicitement cette variable à l'extérieur de cette portée (avec un return par exemple, ou en la mettant dans une variable lexicale d'une portée extérieure).

    En résumé, avec des handles lexicaux, même si tu oublies de les fermer, les fichiers se refermeront d'eux-même très vite, pas avec des handles GLOB. Pour un petit programme, ça ne fera aucune différence, pour un gros ou même un moyen, ça peut en faire une grosse !
    De plus les handles lexicaux ont d'autres avantages, qui les rendent plus sûrs à utiliser.

    --
    Jedaï

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    IAISSE ! iou are ze beste !
    ça fonctionne parfaitement maintenant.

    Citation Envoyé par Jedai
    Et ça ça marche ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    next if $nom_source =~ m/^\.\.?$/; # pseudo-dossiers . et ..
    "$dossier/$fichier" marche sous Windows (du moins sous les NT, 2000 et XP et très probablement Vista) et sous Linux/Unix/BSD/MacOSX/... (pas VMS probablement et pas Mac Classic), tu lances bien ton script à partir du répertoire dans lequel se trouve le dossier "mars" ?

    --
    Jedaï
    Qu'est-ce qui n'allait pas dans la version précédente ? Est-ce parce que le programme butait sur les dossiers invisibles (les mêmes que ceux qui étaient comptabilisés dans le programme exemple "Handle de répertoire" : 20 fichiers, 2 répertoires) ?

    ça marche !!! N'empêche, j'aimerais bien savoir aller chercher mon fichier source sans avoir à le copier côté du programme...

    Merci beaucoup.

  7. #7
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par apprenti doc
    ça marche !!! N'empêche, j'aimerais bien savoir aller chercher mon fichier source sans avoir à le copier côté du programme...

    Merci beaucoup.
    Tu n'es pas obligé d'avoir le script dans le même répertoire que ton dossier "mars", l'important c'est de le lancer à partir de ce répertoire (autrement dit, que ce répertoire soit le répertoire de travail au démarrage du script). Par exemple tu peux tout à fait mettre le script où tu veux et faire un raccourci vers lui qui spécifie le répertoire de travail que tu veux.
    Par ailleurs, tu pourrais très bien mettre des chemins absolus plutôt que relatif, et alors tu peux même lancer le script d'où tu veux.

    --
    Jedaï

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jedai
    Tu n'es pas obligé d'avoir le script dans le même répertoire que ton dossier "mars", l'important c'est de le lancer à partir de ce répertoire (autrement dit, que ce répertoire soit le répertoire de travail au démarrage du script). Par exemple tu peux tout à fait mettre le script où tu veux et faire un raccourci vers lui qui spécifie le répertoire de travail que tu veux.
    Par ailleurs, tu pourrais très bien mettre des chemins absolus plutôt que relatif, et alors tu peux même lancer le script d'où tu veux.
    Concrètement, admettons que j'aie (pour faire simple) un dossier 'Extraction' dans 'Mes documents'. A l'intérieur de ce dossier, j'ai un dossier 'Fichiers_log_bruts' (avec les sources) et un dossier 'Test_du_programme' (avec le programme 'extract_sauv.pl'). Que dois-je écrire (pour les chemins relatif et absolu) ?
    ...Peut-être que j'abuse (?). Renvoies-moi aux tutoriels ! ...mais dis-moi où !

    Encore merci.

  9. #9
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par apprenti doc
    Concrètement, admettons que j'aie (pour faire simple) un dossier 'Extraction' dans 'Mes documents'. A l'intérieur de ce dossier, j'ai un dossier 'Fichiers_log_bruts' (avec les sources) et un dossier 'Test_du_programme' (avec le programme 'extract_sauv.pl'). Que dois-je écrire (pour les chemins relatif et absolu) ?
    ...Peut-être que j'abuse (?). Renvoies-moi aux tutoriels ! ...mais dis-moi où !

    Encore merci.
    Alors, le chemin relatif sera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '../Fichiers_log_bruts'
    et l'absolu sera
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'C:/Documents and Settings/TonNomDUtilisateur/Mes Documents/Extraction/Fichiers_log_bruts'
    (ouf ! ).
    Bien sûr, dans le second cas ce n'est pas toujours vrai, beaucoup dépend de ta version de Windows, et éventuellement tu peux également avoir déplacé le dossier "Mes Documents", dans ce cas peut-être serait-il préférable d'utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "$ENV{USERPROFILE}/Mes Documents/Extraction/Fichiers_log_bruts"
    --
    Jedaï

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Je te remercie ; ça marche du tonnerre ! Et ça élargit considérablement le champ des possibles .

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

Discussions similaires

  1. Optimisation de la fonction sleep dans un traitement d'image
    Par Traxsilver dans le forum C++Builder
    Réponses: 11
    Dernier message: 13/05/2008, 20h52
  2. Réponses: 15
    Dernier message: 26/03/2008, 19h52
  3. appeler une fonction javascript apres le traitement d'un bouton
    Par apoca dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/09/2007, 16h42
  4. [Configuration] Activé la fonction opendir avec un script php
    Par bsm2006 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 24/02/2007, 04h19
  5. la fonction opendir
    Par thepinguin dans le forum C
    Réponses: 4
    Dernier message: 10/11/2006, 18h20

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