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 :

Lecture de la fin d'un fichier


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 44
    Points : 32
    Points
    32
    Par défaut Lecture de la fin d'un fichier
    Bonjour,

    Je voudrais vérifier que les deux derniers caractères d'un fichiers soient bien \x0d\x0a (saut de ligne windows).

    Je procéde de la façon suivante :
    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
     
    # Fichier à controler
    my $file = 'test.txt';
     
    # Ouverture du fichier
    open (FILE, $file) or die "Impossible d'ouvrir le fichier : $!\n";
     
    # On se place à la fin du fichier - 2 caractères
    seek (FILE, -2, 2);
     
    # Lecture des deux caractères
    my $ligne = '';
    read ( FILE, $ligne, 2 );
     
    # Affichage du résultat
    print "\nDEUX DERNIERS CARACTERES = '$ligne'\n";
    print "\nDEUX DERNIERS CARACTERES CORRECTS\n" if ($ligne =~ m/^\x0d\x0a$/);
     
    # Fermeture du fichier
    close FILE;
    Je ne comprend pas pourquoi ça ne marche pas... (bien sur quand je regarde le fichier dans un éditeur hexa, il se termine bien par les caractères voulu).

    Si quelqu'un veut bien m'expliquer, merci

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 582
    Points : 2 030
    Points
    2 030
    Par défaut
    Bonjour,

    si tu recherches exactement la chaîne "\x0d\x0a", il faut je pense doubler tes 2 \ dans ton expression régulière. Le \ étant un caractère d'échappement...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print "\nDEUX DERNIERS CARACTERES CORRECTS\n" if ($ligne =~ m/^\\x0d\\x0a$/);
    Mais peut être dis-je une bêtise ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 44
    Points : 32
    Points
    32
    Par défaut
    Non, pour rechercher à l'aide de caractères hexa dans une expression réguliére, il faut toujours passer simple \x , sinon, ils ne sont pas reconnus comme des caractères hexa. (car 0d et 0a correspondent au retour chariot et au saut de ligne en hexa).

    Sinon, avec \r\n, ça ne marche pas non plus.

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 582
    Points : 2 030
    Points
    2 030
    Par défaut
    Ok, désolé

    Par contre, si les lignes de ton fichier se terminent par "\r\n", ça signifie quand même que le fichier texte est du windows, non ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 44
    Points : 32
    Points
    32
    Par défaut
    Oui, c'est ça, je veux vérifier que mon fichier se termine par un saut de ligne windows. Mais je ne sais pas comment faire

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2003
    Messages
    1 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 1 582
    Points : 2 030
    Points
    2 030
    Par défaut
    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
    # Fichier à controler
    my $file = 'test.txt';
     
    # Ouverture du fichier
    open (FILE, $file) or die "Impossible d'ouvrir le fichier : $!\n";
     
    # On ne teste qu'une ligne pour voir si elle contient la séquence "\r\n"
    while(<FILE>)
    {
        if ($_ =~ /\r\n$/)
        {
            print "j'ai trouvé la séquence !\n";
            close(FILE);
        }
    }
    Le close dans mon code est un peu brutal

    Sinon, charger la totalité du fichier dans un tableau (ou liste) et vérifier sur un des éléments s'il se termine par "\r\n" ?

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 44
    Points : 32
    Points
    32
    Par défaut
    Dans ton exemple, on detecte uniquement si une des lignes du fichier se termine par la séquence \r\n (saut de ligne windows), ce qui a de forte chance de survenir dés la première ligne du fichier.

    Or moi, je veux detecter non pas qu'une des lignes se termine par \r\n mais que mon fichier se termine par \r\n.

    De plus j'ai un soucis de performance, donc je ne peux pas procéder en parcourant l'intégralité du fichier pour aller lire ses 2 derniers caractères (si j'ai un fichier de 150mo, ce qui sera mon cas en moyenne, je ne peux pas me permettre de le lire en entier uniquement pour récupérer ses 2 derniers carcatères). D'ou l'utilisation de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # On se place à la fin du fichier - 2 caractères
    seek (FILE, -2, 2);
    qui me permet de me positionner directement 2 caractères avant la fin du fichier.
    Bien sur, je ne peux même pas espérer stocker mon fichier dans un tableau : imagine 150mo dans un tableau, et ce sur 40 instances de mon programme Ma machine va exploser ...

  8. #8
    Jeh
    Jeh est déconnecté
    Membre actif Avatar de Jeh
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 203
    Points : 250
    Points
    250
    Par défaut
    tu as essayé ton expression régulière après avoir passé ton $ligne en hexa ?
    Car pour moi, tu récupères dans $ligne seulement tes caratères au format texte, mais je me trompe peut être, je n'ai jamais fait ce genre de manip'...
    Sinon, pour info, le 'm' dans ta regexp ne sert à rien quand tu as une regexp dans une condition.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 44
    Points : 32
    Points
    32
    Par défaut
    tu as essayé ton expression régulière après avoir passé ton $ligne en hexa ?
    Car pour moi, tu récupères dans $ligne seulement tes caratères au format texte, mais je me trompe peut être, je n'ai jamais fait ce genre de manip'...
    Non, mais j'ai essayé avec \r\n, et de plus, j'ai souvent utilisé ce genre de syntaxe et je suis sur qu'elle fonctionne.
    Sinon, pour info, le 'm' dans ta regexp ne sert à rien quand tu as une regexp dans une condition.
    Je le met uniquement pour améliorer la lisibilité

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 427
    Points : 459
    Points
    459
    Par défaut
    si tu veux chooper juste les 2 derniers octets du fichier tu peux utiliser seek :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    open(my $fh, "<", $file) || die $!;
    binmode($fh); # tres important si tu ne veux pas qu'il fasse lui meme la conversion sans te le dire sous windows !
    seek($fh, -2, 2);
    my $chars = <$fh>;
    close($fh);
    print $chars eq "\015\012" ? "windows\n" : "non windows\n"
    (non testé)


    EDIT: en fait je vois que tu utilisais deja seek. Mais inutile d'utiliser une regepx ensuite puisque tu sais que tu a deux chars. Ton probleme venait peut etre de l'absence de binmode, si tu lancais ton script sous windows

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 44
    Points : 32
    Points
    32
    Par défaut
    Enfin, j'ai réussi (testé sous windows et aix) :
    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
    my $file = 'test.txt';
     
    my $temp = $/;
    $/ = "\0";
     
    open (FILE, $file) or die "Impossible d'ouvrir le fichier : $!\n";
    binmode FILE;
     
    seek (FILE, -1, 2);
     
    my $ligne = <FILE>;
     
    print "\nDEUX DERNIERS CARACTERES = '$ligne'\n";
     
    print "\nDEUX DERNIERS CARACTERES CORRECTS\n" if ($ligne eq "\015\012");
     
    close FILE;
     
    $/ = $temp;
    Merci pour le binmode pospos

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    427
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 427
    Points : 459
    Points
    459
    Par défaut
    pour le $/ mieux vaut le redefinir avec un local dans un bloc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    {
      local $/ = undef;
      $buf = <FILE>;
    }
    (ou utiliser read() comme tu le faisais. Ca passe pas le <FILE> si tu redefini pas $/ ?)

    et sinon je te conseil aussi d'utiliser une vraie variable à la place de FILE, et de faire un open a trois arguments (imagine ce qui se passe si un mec rentre ">text.txt" comme nom de fichier, ou pire un truc avec un pipe...)

    et sinon je comprend pas pk tu fais -1 dans le seek?...

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

Discussions similaires

  1. Réponses: 22
    Dernier message: 26/09/2006, 01h36
  2. [Fortran] Lecture de la fin d'un fichier
    Par sebduth dans le forum Fortran
    Réponses: 1
    Dernier message: 02/09/2005, 16h27
  3. [JList] Lecture des données sauvegardées dans un fichier
    Par Myogtha dans le forum Composants
    Réponses: 7
    Dernier message: 10/06/2004, 21h05
  4. [C#] [.NET] Lecture d'une classe dans un fichier
    Par niPrM dans le forum Windows Forms
    Réponses: 4
    Dernier message: 18/05/2004, 08h57
  5. lecture de données a partir de fichier
    Par sana dans le forum MFC
    Réponses: 5
    Dernier message: 21/01/2004, 12h57

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