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 Delphi Discussion :

TFilestream, Exception et methode Free


Sujet :

Langage Delphi

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 298
    Points : 318
    Points
    318
    Par défaut TFilestream, Exception et methode Free
    J'ai un problème lors de la libération d'un tfilestream :

    J'ai un message d'erreur (violation access) lors de la libération du fichier (Free) s'il y a eu une exception lors du create alors que d'après l'aide la methode Free marche même si l'objet n'est pas initialisé

    Est-ce normal ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    procedure TForm1.Button1Click(Sender: TObject);
    var
    	fichier: TFileStream;
    begin
        try
            fichier := TFileStream.Create('test.txt', fmOpenWrite or fmShareExclusive);
        except
           // On
           MessageDlg('Erreur ouverture', mtError, [mbOK], 0);
        end;
        fichier.Free;
    end;

  2. #2
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut
    Pour pas t'embêter avec ça, utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      FreeAndNil(fichier);
    Ca fait le même chose, ça met à nil et puis ça vérifie que ça existe...
    Tu peux aussi faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      if Assigned(fichier) then fichier.free;
    Mais je pense aussi que tu dois te tromper dans l'ordre de ton code...
    Bonne chance

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 298
    Points : 318
    Points
    318
    Par défaut
    J'ai essayé FreeAndNil et le test avec assign et j'ai toujours un violation access à la libération.

    En fait il faut initialiser fichier à nil avant de faire le create. Apparamment en cas d'exception dans le create, la variable n'est pas modifiée et contient n'importe quoi puisque c'est une variable locale.

    C'est en C++ que la variable est initialisée à NULL en cas de problème lors de la création d'un objet ?

  4. #4
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Essaie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        try 
            fichier := TFileStream.Create('test.txt', fmOpenWrite or fmShareExclusive); 
        except 
           MessageDlg('Erreur ouverture', mtError, [mbOK], 0); 
        finally
           fichier.Free; 
        end;
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        try 
            fichier := TFileStream.Create('test.txt', fmOpenWrite or fmShareExclusive); 
           fichier.Free; 
        except 
           MessageDlg('Erreur ouverture', mtError, [mbOK], 0); 
        end;
    Bonne chance

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mars 2003
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mars 2003
    Messages : 20
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    Essaie plutôt d'utiliser un TStream à la place d'un TFileStream

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      Stream: TStream;
    begin
      Stream := TFileStream.Create(FileName, fmOpenRead or  fmShareDenyWrite);
      try
        LoadFromStream(Stream);
      finally
        Stream.Free;
      end;
    end;
    Bonne chance

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 298
    Points : 318
    Points
    318
    Par défaut
    Citation Envoyé par Pedro204
    Essaie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        try 
            fichier := TFileStream.Create('test.txt', fmOpenWrite or fmShareExclusive); 
        except 
           MessageDlg('Erreur ouverture', mtError, [mbOK], 0); 
        finally
           fichier.Free; 
        end;
    ou bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
        try 
            fichier := TFileStream.Create('test.txt', fmOpenWrite or fmShareExclusive); 
           fichier.Free; 
        except 
           MessageDlg('Erreur ouverture', mtError, [mbOK], 0); 
        end;
    Bonne chance
    Le problème avec delphi est que le try except finally n'existe pas, la deuxième solution ne me plais pas car en cas d'erreur dans un write le fichier n'est pas libéré. J'ai essayé avec un TStream et c'est le même problème.

    Une solution est d'initialiser la variable à nil avant de faire le create, je pensait qu'elle était initialisé même en cas d'erreur par le create.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        try
            fichier := nil;
            fichier := TFileStream.Create('test.txt', fmOpenWrite or fmShareExclusive);
        except
           MessageDlg('Erreur ouverture', mtError, [mbOK], 0);
        end;
           fichier.Free;
        end;

  7. #7
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    La méthode la plus sûre utilisée est celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Objet := TClasse.Create;
    try
      // Utilisation de Objet.
    finally
      Objet.Free;
    end;
    Cependant ce code ne permet pas d'intercepter l'erreur s'il y lieu. Voici donc une modif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    try
      Objet := TClasse.Create;
    except
      on Error : Exception do
      begin
        // ...
        exit;
      end;
    end;
    try
      // Utilisation de Objet
    finally
      Objet.Free;
    end;

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    322
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2009
    Messages : 322
    Points : 310
    Points
    310
    Par défaut
    J'ai ce problème quand

    J'ai une application qui est en train d'écrire un fichier
    J'ai une autre application qui est en train de lire le même fichier.

    Ce code ne fonctionne pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try
      fs:=tfilestream.create(fichier,fmOpenRead OR fmshareexclusive);
    except
      fs.Free;//ce free déclenche occasionnellement une erreur: étrange.
      exit;
    end;
    En n'appelant pas le free, pas d'erreur incontrôlable.

    Ce code fonctionne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     try
      fs:=tfilestream.create(fichier,fmOpenRead OR fmshareexclusive);
    except
      try  
        fs.Free;
      except
      end;
      exit;
    end;

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 586
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 586
    Points : 25 262
    Points
    25 262
    Par défaut
    Citation Envoyé par sgmsg Voir le message

    Ce code ne fonctionne pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try
      fs:=tfilestream.create(fichier,fmOpenRead OR fmshareexclusive);
    except
      fs.Free;//ce free déclenche occasionnellement une erreur: étrange.
      exit;
    end;
    Tu ne comprends pas ce que tu fais ?
    Si une exception se déroule durant tfilestream.create, la variable fs n'est jamais affecté, le Free se produit donc sur une variable à une valeur aléatoire ce qui provoque des Violation d'Accès tout aussi aléatoire, mais lorsqu'il n'y a pas d'erreur, cela ne veut pas dire que c'est bon, cela a modifié une zone mémoire accessible par ton programme on ne sait pas vraiment comment, les résultats pouvant se manifester dans une toute autre partie du code !

    Citation Envoyé par sgmsg Voir le message
    Ce code fonctionne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     try
      fs:=tfilestream.create(fichier,fmOpenRead OR fmshareexclusive);
    except
      try  
        fs.Free;
      except
      end;
      exit;
    end;
    Ce code protège l'exception du tfilestream.create et protrège contre un appel dangereux à Free précisémment là où il ne faut surtout pas l'appeler

    Ne bricole pas n'importe quoi !

    Pour revenir à la réponse de SJRD qui comme d'habitude apporte une vraie réponse, je corrigerais l'utilisation du "exit" qui apporte une rupture dans le code qui n'est pas facile à détecter !

    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
     
    try
      Objet := TFileStream.Create('...', fmOpenRead);
      try
        try
          // Utilisation de Objet TFileStream
        except
           on Error : ETypedException do // je préfère savoir ce que j'attrape
           begin
             // Erreur prévue durant l'utilisation TFileStream
           end;
        end;
      finally
        Objet.Free;
      end;
    except
      on Error : EFOpenError do // fmOpenRead donnera un EFOpenError et fmCreate donnera un EFCreateError  
      begin
        // Erreur durant la création de l'objet TFileStream en Lecture 
      end;
      on Error : Exception do  
      begin
        // Erreur non prévue durant l'utilisation ou la création
      end;
    end;

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 21/04/2011, 14h56
  2. [Reflexivite]exception ArrayIndexOutOfBoundsException methode invoke
    Par caro_a dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 12/07/2006, 11h35
  3. Réponses: 9
    Dernier message: 19/10/2005, 04h35
  4. Réponses: 5
    Dernier message: 07/07/2005, 10h20
  5. [Exception]Connaitre la pile d'appel de classes/méthodes
    Par salome dans le forum Général Java
    Réponses: 2
    Dernier message: 19/03/2005, 20h21

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