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

Entrée/Sortie Java Discussion :

Fermeture de flux


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Llo
    Llo est déconnecté
    Membre averti
    Inscrit en
    Janvier 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 16
    Par défaut Fermeture de flux
    Bonjour,

    Suite à une remontée d'anomalie, je suis actuellement en train de vérifier le code d'un composant RMI Java permettant de copier le contenu d'un répertoire d'un serveur vers un répertoire d'un autre serveur.

    Après avoir fouillé le code et rechercher des infos sur le net, je suis arrivé à la conclusion que l'erreur venait d'une concurrence d'accès sur un fichier déjà ouvert (FileNotFoundException lors de l'instanciation d'un FileInputStream ou d'un FileOutputStream).
    En effet, le fichier provoquant l'erreur existe bien.

    Le code ci-dessous montre que les FileInputStream/FileOutputStream ne sont pas fermés (détruits) après utilisation.

    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
    39
    40
     
    // Déclaration des buffers
    FileInputStream fi;
    BufferedInputStream in;
     
    FileOutputStream fo;
    BufferedOutputStream out;
     
    try
    {
    // Ouverture d'un buffer de lecture de fichier
    fi = new FileInputStream(dirPub + nomfic);
    in = new BufferedInputStream(fi,BUFFER_SIZE);
     
    // Ouverture d'un buffer d'ecriture de fichier
    fo = new FileOutputStream(dirPro + nomfic);
    out = new BufferedOutputStream(fo,BUFFER_SIZE);
     
    // Copie du fichier
    int c;	        
    byte b[] = new byte[BUFFER_SIZE];
     
    while ((c = in.read(b)) != -1)
    	out.write(b, 0, c);
    	in.close();
    	out.close();
     
    	// On positionne la date de derniere modification du fichier de production à la date de dernière modification du fichier en publication
    	new File(dirPro + nomfic).setLastModified(new File(dirPub + nomfic).lastModified());
     
    } 
    catch (FileNotFoundException fnf) 
    {
    	//Traitement de la FileNotFoundException
    	// C'est cette exception qui est levée lors de l'instanciation du FileInputStream
    }
    catch (IOException ioe)
    {
    	// Traitement de l'IOException
    }
    Or, les fichiers sont déjà accédés un peu plus tôt lors de l'appel dans une autre méthode du composant. Et de la même manière, les FileInputStream instanciés ne sont pas fermés.

    En ayant trouvé des infos ici :
    http://www.developpez.net/forums/sho...d.php?t=443600
    là :
    http://www.developpez.net/forums/sho...d.php?t=200740
    et là :
    http://java.developpez.com/faq/java/...ererRessources

    je penche vraiment pour ce type d'erreur. J'ai d'ailleurs un "Permission denied" dans le message de l'exception qui vient renforcer cette idée.

    Du coup, j'essaie de reproduire le cas d'erreur en local sur ma propre machine et là, surprise : pas de plantage. Que je teste avec une copie de 1 fichier ou 10 ou 50000, le traitement se déroule correctement. Pas facile de valider une correction si on n'arrive pas à reproduire le cas d'erreur d'origine...

    Auriez-vous une idée pour reproduire un cas de fichier déjà ouvert en local?

    J'ai trouvé une phrase d'un support de cours qui me fait penser que l'environnement d'exécution pourrait jouer un rôle que je ne connais pas :
    Classe FileOutputStream : java.io.FileOutputStream
    Un flux de sortie de fichier est un flux de sortie permettant d’écrire des données dans un fichier ou dans un FileDescriptor. Qu’un fichier soit disponible ou puisse être créé dépend de la plate-forme sous-jacente. Certaines plates-formes autorisent un fichier à être ouvert en écriture par un seul FileOutputStream à la fois. Dans de telles situations les constructeurs de cette classe échouent si le fichier est déjà ouvert.
    issue de : http://www.ensg.ign.fr/FAD/FAD_PDF/c.../IntroJava.pdf

    En lisant ceci, j'en viens à me dire que c'est peut-être l'environnement de production qui provoque ce blocage. Le serveur de production est un Solaris équipé Sun de la tête au pied (y compris la version du jdk qui est fournie par Sun si j'ai bien compris ce qu'on m'a dit).

    Auriez-vous entendu parler de ce genre de problème lié au système utilisé?

    Toute aide ou info est la bienvenue.

    D'avance merci.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il y a de forte chance que le problème viennent de là... Mais comme tu le dis la gestion des fichiers est fortement dépendante du système, et cela peut donc provoquer des erreurs différentes.

    Par exemple sous Windows il est impossible de supprimer un fichier ouvert (que ce soit en lecture ou écriture), alors que cela ne pose pas de problème sous Linux...


    J'ignore complètement les règles de gestion de fichier de Solaris, mais peut-être que tu devrais lancer ton programme de test sur ce système




    Enfin même si ton problème ne vient pas de là la non-fermeture des flux, qui entraine non-seulement une utilisation inutile des ressources, mais pourrait poser d'autre problème sur un serveur dans le cadre d'une utilisation intensive (comme atteindre la limite de fichier ouvert ).


    a++

  3. #3
    Llo
    Llo est déconnecté
    Membre averti
    Inscrit en
    Janvier 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 16
    Par défaut
    Merci adiGuba pour ta réponse.

    Effectivement, la première chose à faire lors de la correction sera de remettre un code propre avec fermeture des flux pour éviter la fuite des ressources à l'étranger...
    Le problème, c'est que si j'effectue ma modification avant d'avoir pû reproduire le cas d'erreur, je ne peux garantir la pertinence de ma correction.

    Du coup, il ne reste qu'une solution : Faire ma modification et reposer le composant en production pour voir si l'erreur persiste. Niveau qualité, on a connu mieux comme logique de test...
    Mais, même en le posant en production, vu que l'erreur semble aléatoire (ça me fait bizarre de dire ça en parlant d'informatique), rien ne me garantit que le traitement sera fiable, même s'il se déroule correctement pendant toute la durée de mes essais...

    Je vais essayé de trouver des informations sur la gestion de fichiers sur Solaris des fois que la réponse me sauterait aux yeux.

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Llo Voir le message
    Du coup, il ne reste qu'une solution : Faire ma modification et reposer le composant en production pour voir si l'erreur persiste. Niveau qualité, on a connu mieux comme logique de test...
    Tu ne peux vraiment pas exécuter une petite appli de test sur le serveur de production sans repasser l'application de prod ?

    Citation Envoyé par Llo Voir le message
    Mais, même en le posant en production, vu que l'erreur semble aléatoire (ça me fait bizarre de dire ça en parlant d'informatique), rien ne me garantit que le traitement sera fiable, même s'il se déroule correctement pendant toute la durée de mes essais...
    Le coté aléatoire peut s'expliquer par le fait que les flux mettent en place des gardes-fou via les finalize : lorsque l'objet représentant le flux est libéré il ferme le fichier qui lui est associé... mais comme on ne maitrise pas le moment de la libération par le GC il ne vaut mieux pas se baser dessus

    a++

  5. #5
    Llo
    Llo est déconnecté
    Membre averti
    Inscrit en
    Janvier 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 16
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Tu ne peux vraiment pas exécuter une petite appli de test sur le serveur de production sans repasser l'application de prod ?
    C'est effectivement ce qu'il va se passer au final. Après une batterie de tests en local, puis en environnement d'intégration, le composant corrigé sera déposé en production avec une application spécifique qui l'appellera. On sort la grosse artillerie en fait!

    Je n'ai pas trouvé de documentation concernant la gestion de fichiers au niveau des serveurs. Les tests devraient validé les corrections sans avoir besoin de fouiller plus avant dans le comportement des serveurs.

    Du coup, ce sujet peut-être marqué comme résolu même si je n'ai pas de vraie réponse à ma question.

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

Discussions similaires

  1. InputStream et fermeture de flux
    Par Mides dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 19/06/2012, 11h54
  2. help ! fermeture d’un flux video en AS3
    Par cyberbelette dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 12/03/2010, 09h07
  3. Réponses: 3
    Dernier message: 29/03/2008, 09h17
  4. [VB6] [MDI] Signaler la fermeture d'une fille à la mère
    Par cpri1shoot dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 13/04/2004, 08h57
  5. [reseaux] redirection de flux
    Par Olive1808 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 12/08/2002, 09h24

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