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 :

Fichier ecrit par un Thread et lu par un autre Thread


Sujet :

Entrée/Sortie Java

  1. #1
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : janvier 2004
    Messages : 1 249
    Points : 1 538
    Points
    1 538
    Par défaut Fichier ecrit par un Thread et lu par un autre Thread
    Bonjour,

    j'ai une application répartie basée sur le systeme de fichier de linux.

    J'ai un Thread qui ecrit un fichier et un autre qui attend que le fichier existe et que sa taille soit differente de zero avant de le lire.

    Le probleme est qu'il arrive (c'est aléatoire meme si c'est relativement rare) sur des gros fichiers (plus de 8ko) que le fichier ecrit ne s'ecrive pas completement ! (il fait pile 8192 octets au lieu de 9976) Du coup, la lecture est partielle, et mon application tombe (je lis un flux xml)

    Comment est-ce possible ? y a t'il des précautions particulieres a prendre ?

    Je vous donne le code des deux fonctions appelés par les thread :

    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
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    /**
     * Ecrit une chaine dans un fichier
     * @param filename Le nom du fichier a ecrire
     * @param content La chaine a ecrire dans le fichier
     */
    	public static void put(String filename, String content) {
    System.out.println("Put "+filename+"...");		
    		File f=new File(filename);
     
    		try {
    			FileOutputStream fos=new FileOutputStream(f);
     
    			fos.write(getEncodingBytes(content));	// ecriture...
     
    			fos.flush();
    			fos.close();
     
    			fos=null;
     
    		} catch (Exception ex) {
    			error("Erreur d'E/S flux sortant pour ecriture de "+content.length()+" octets dans "+filename);
    			ex.printStackTrace();
    		}
    		f=null;
    System.out.println("Put "+filename+" OK");		
    	}
     
    /**
     * Lit le fichier et renvoi une chaine de caractere
     * @param filename Le nom du fichier a lire
     * @return Le contenu du fichier
     */	
    	public static String read(String filename) {
    		String content="";
    		int bufferSize=1024;
     
    		byte[] buffer=new byte[bufferSize];
     
    		int lus=0;
     
    		FileInputStream fis=null;
    		File f;		
    System.out.println("Try to read "+filename+"...");		
    		waitUntilExist(filename);	// attente jusqu'a ce que le fichier existe et que la taille soit differente de 0
    		f=new File(filename);
     
    		content="";
    		try {
    			fis=new FileInputStream(f);	// creation du flux
     
    			while ((lus=fis.read(buffer))!=-1) {
    				content+=getEncodingString(buffer, 0, lus);	// concatenation du contenu
    			}
    			fis.close();
    			fis=null;
     
    		} catch (Exception ex3) {
    			error("Erreur d'E/S flux entrant sur "+filename);
    			ex3.printStackTrace();
    		}
     
    		buffer=null;
    		f=null;		
     
    System.out.println("Read "+filename+" OK");
    		return content;	
    	}
     
     
    /**
     * Attend que le fichier passé en parametre existe en faisant un sleep sur le thread courant
     * @param filename Le nom du fichier a attendre
     */	
    	public static void waitUntilExist(String filename) {
    		File f=new File(filename);
    System.out.println("Waiting "+filename+" exist...");
    		// attente jusqu'a ce que le fichier existe
    int i=0;
    		while (!f.exists() || (f.length()==0)) {
    i++;
    System.out.print("w");
    				try {
    					Thread.sleep(300); // attente 300ms
    					i++;
    				} catch (Exception ex) {}
    		}
    		f=null; 	
    System.out.println("Sleeping "+300*i+" ms");		
    	}
    Merci ;o)

    Fladnag

    PS : les instructions qui ne sont pas indentées sont des instructions de debuggage, elles n'ont pas d'influence sur le reste du code...

  2. #2
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : février 2004
    Messages : 1 259
    Points : 1 936
    Points
    1 936
    Par défaut
    Le probleme c'est surement que le fichier n'est pas completement ecris lorsque la lecture commence..

    Pour eviter ce probleme tu peux essayer de synchronizer les deux methodes, change juste leurs declarations comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public static synchronized void put(String filename, String content)...
     
    public static synchronizedString read(String filename)...
    Cela empechera de commencer la lecture si une ecriture est en cours ...

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  3. #3
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : janvier 2004
    Messages : 1 249
    Points : 1 538
    Points
    1 538
    Par défaut
    Ok, merci, ca a l'air de marcher apres une petite adaptation...

    Dans mes fonctions, le lecteur rentre d'abord dans la fonction, "s'endort" dedant en attendant la creation du fichier par le redacteur. J'ai donc modifié le code du lecteur par :

    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
    41
    42
    43
    44
    45
    46
    47
     
    /**
     * Lit le fichier et renvoi une chaine de caractere
     * @param filename Le nom du fichier a lire
     * @return Le contenu du fichier
     */	
    	public static String read(String filename) {
     
    System.out.println("Try to read "+filename+"...");		
    		waitUntilExist(filename);	// attente jusqu'a ce que le fichier existe et que la taille soit differente de 0
     
    		return read2(filename);
    	}
     
    	synchronized public static String read2(String filename) {
    		String content="";
    		int bufferSize=1024;
     
    		byte[] buffer=new byte[bufferSize];
     
    		int lus=0;
     
    		FileInputStream fis=null;
    		File f;		
     
    		f=new File(filename);
    		content="";
    		try {
    			fis=new FileInputStream(f);	// creation du flux
     
    			while ((lus=fis.read(buffer))!=-1) {
    				content+=getEncodingString(buffer, 0, lus);	// concatenation du contenu
    			}
    			fis.close();
    			fis=null;
     
    		} catch (Exception ex3) {
    			error("Erreur d'E/S flux entrant sur "+filename);
    			ex3.printStackTrace();
    		}
     
    		buffer=null;
    		f=null;		
     
    System.out.println("Read "+filename+" OK");
    		return content;			
    	}
    En rajoutant le synchonized sur le redacteur

    Cependant, y aurais t'il un autre moyen ?

    Car pour l'instant, je fait tourner l'application en local, mais a terme, ca sera sur le mode client/serveur, donc le lecteur sera sur une machine (une jvm) et le redacteur sur une autre jvm... je ne pense pas que les synchonized fonctionneront entre 2 jvm sur 2 machines differentes...

  4. #4
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : février 2004
    Messages : 1 259
    Points : 1 936
    Points
    1 936
    Par défaut
    Je ne pense pas non plus qu'un client et un serveur tournent sur la meme machine avec le meme disque donc il ne s'agira plus de lire/ecrire le meme fichier mais d'un autre probleme ...

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  5. #5
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : janvier 2004
    Messages : 1 249
    Points : 1 538
    Points
    1 538
    Par défaut
    si, c'est possible ;o)

    En fait, mon programme doit servir de demo, et on voulait faire tourner le serveur sur une machine linux et le client sur une machine windows qui monte la partition linux a travers le reseau !

    donc c'est toujours de l'ecriture/lecture de fichier, mais avec 2 jvm differentes...

  6. #6
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : février 2004
    Messages : 1 259
    Points : 1 936
    Points
    1 936
    Par défaut
    Ce que tu peux faire dans ce cas, c'est utiliser une socket de "controle" qui informe le client que l'ecriture est finie du cote serveur...

    A mon avis ce serait plus simple de balancer directement le fichier XML sur la socket, mais bon c'est toi qui voit

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  7. #7
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : janvier 2004
    Messages : 1 249
    Points : 1 538
    Points
    1 538
    Par défaut
    ok, merci ;o)

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

Discussions similaires

  1. Thread attendant les messages d'autres Thread
    Par Christophe_ dans le forum Général Java
    Réponses: 3
    Dernier message: 09/12/2009, 12h05
  2. quels fichiers ouverts ou tentés d'être ouverts par une application
    Par jean-jacques varvenne dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 17/09/2007, 10h19
  3. Réponses: 4
    Dernier message: 04/09/2007, 13h13
  4. [Thread] Reveiller un thread a partir d'un autre thread d'une autre classe
    Par arnolpourri dans le forum Concurrence et multi-thread
    Réponses: 18
    Dernier message: 11/04/2007, 15h18
  5. Trier les fichiers par type et les afficher par groupe ...
    Par KneXtasY dans le forum Autres Logiciels
    Réponses: 4
    Dernier message: 18/09/2005, 18h50

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