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 :

Programmation Socket : problème lors de l'envoie du fichier.


Sujet :

Entrée/Sortie Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    Points : 85
    Points
    85
    Par défaut Programmation Socket : problème lors de l'envoie du fichier.
    Bonjour,

    Je souhaite transférer un fichier .avi par socket d'un PC à un autre (client/serveur)

    Or je veux que mon programme s'exécute sans arrêt et à chaque fois qu'il trouve un fichier .avi dans le client (Pc1), il l'envoie au PC2 (serveur).

    Mon code est composé de trois classes : (voir le code)

    -Une classe rep_client qui fait appel à la classe Client.

    -Deux classes (Client et serveur)

    Mon code fonctionne bien, le serveur est sur écoute pas de problème d'exécution sauf que dans le cas où j'ajoute un nouveau fichier au dossier client pour qu'il puisse être envoyé, un message d'erreur s'affiche me signalant que
    Le processus ne peut pas accéder au fichier car ce fichier est utilisé par un autre processus
    En effet le problème c'est qu'il faut attendre que l'ensemble du fichier soit ajouté au dossier du client : j'explique si la taille du fichier est de 200 Mo (il faut attendre le temps de copie du fichier afin de l'envoyer par la suite au serveur).

    Que dois je-faire ?

    Merci de votre aide
    Rep_Client :
    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
     
     
    package File;
    import java.io.* ;
     
    public class rep_client {
    public static void liste(String a){
    while (true){  // boucle infinie
    File repertoire = new File(a);
    String [] listefichiers;
    listefichiers=repertoire.list();
     
    System.out.print("j'ai trouvé un fichier fichier :p");
     
    int i;
     
    for(i=0;i<listefichiers.length;i++){
    if(listefichiers[i].endsWith(".avi")==true){
    System.out.println(a+"\\"+listefichiers[i]);
    String target1=a+"\\"+listefichiers[i];
    Client.envoie(target1);
     
    // supression du fichier après envoie
    //File supfichier= new File(a+"\\"+listefichiers[i]);
    //supfichier.delete() ;
    //System.out.print("test1");
        }
    }
     
    }
    }
    	public static void main(String[] args) {
    	// le chemin ou se situe les fichiers côté client
     
                //System.out.print("test2");
                liste("D:\\mon_dossier_ou_se_situe_les_fichiers");   } 
     
     
     
    }
    Client :
    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
     
     
    package File;
    import java.io.*;
    import java.net.*;
     
     
    public class Client {
      public static void envoie (String chemin)
        {
     
            try
            { 
                Socket s=new Socket("localhost",7777);
     
     
     
                    BufferedOutputStream out = new BufferedOutputStream( s.getOutputStream() );
                    FileInputStream filein = new FileInputStream(chemin);
                    byte[] buffer = new byte[8192];
                    int bytesRead =0;
                    while ((bytesRead = filein.read(buffer)) > 0) {
                        out.write(buffer, 0, bytesRead);
                    }
     
                    out.flush();
                    out.close();
                    filein.close();
                    File supfichier= new File(chemin);
                    supfichier.delete() ;
                    s.close();
     
            }catch (IOException e){System.out.println("IO error"+e);};
     
     
            }
    }
    Serveur :
    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
     
     
    package File;
    import java.io.*;
    import java.net.*;
     
     
    public class server2 {
     
          public static void me(Socket n,String ch)
        {
     
            try
            {    InputStream in = n.getInputStream();
              FileOutputStream out = new FileOutputStream("D:\\test\\test2\\"+ch+".avi");
               byte[] buffer = new byte[8192];
                    int bytesRead =0;
                    while ((bytesRead = in.read(buffer)) > 0) {
                        out.write(buffer, 0, bytesRead);
                    }
                 out.flush();
                 out.close();
     
            }catch (IOException e){System.out.println("IO error"+e);};
          }
        public static void main(String args[])
        {int nreq=1;
            try
            {
                ServerSocket sock = new ServerSocket(7777);
                int i=0 ;
     
                for(;;)
                {
     
                    Socket newsock=sock.accept();
                    String sh=Integer.toString(i);
                    System.out.println(sh);
                    me(newsock,sh);
                    i++;
     
                }
            }catch (IOException e){System.out.println("IO error"+e);};
     
     
            }
        }

  2. #2
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 607
    Points : 15 652
    Points
    15 652
    Par défaut
    Même si ça marche actuellement, une boucle infinie me parait un mode de fonctionnement un peu violent. Ton programme va avoir une énorme consommation CPU.
    Tu devrais plutôt utiliser un timer qui vérifie a intervalles régulier.

    Pour se qui est de résoudre ton problème de fichier en cours de copie, je suppose que la copie du fichier pose un verrou en écriture sur le fichier le temps de l'opération.
    Donc tu desvrais utiliser sur le fichier que tu sohaites envoyer un lock ou tryLock. Tant que tu ne peux verrouiller le fichier pour ton application, c'est que la copie doit encore être en cours.

    Si cette méthode ne fonctionne pas, il te reste une méthode plus approximative : on peut supposer que si entre deux vérification séparées de quelques secondes, la taille du fichier n'a pas bougé, c'est que la copie est terminée.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    Points : 85
    Points
    85
    Par défaut
    Citation Envoyé par Uther Voir le message
    Même si ça marche actuellement, une boucle infinie me parait un mode de fonctionnement un peu violent. Ton programme va avoir une énorme consommation CPU.
    Tu devrais plutôt utiliser un timer qui vérifie a intervalles régulier.

    Pour se qui est de résoudre ton problème de fichier en cours de copie, je suppose que la copie du fichier pose un verrou en écriture sur le fichier le temps de l'opération.
    Donc tu desvrais utiliser sur le fichier que tu sohaites envoyer un lock ou tryLock. Tant que tu ne peux verrouiller le fichier pour ton application, c'est que la copie doit encore être en cours.

    Si cette méthode ne fonctionne pas, il te reste une méthode plus approximative : on peut supposer que si entre deux vérification séparées de quelques secondes, la taille du fichier n'a pas bougé, c'est que la copie est terminée.
    Hey Uther, merci pour votre réponse En effet en ce qui concerne la méthode que tu as proposée (comparaison à intervalle de temps de la taille du fichier). Je l'ai essayé, mais ça ne marche pas en effet la méthode relative à la classe File qui permet de renvoyer la taille de fichier l'affiche en totalité bizarre non :p En ce qui concerne le verrouillage du fichier, je n'ai jamais entendu parler de ça (je vais me documenter)
    Enfin tu as mentionné quelque chose de très important : la consommation CPU, je voulais savoir l'intervalle du temps mise entre deux boucles (en nanoseconde ?)

    Merci encore

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 214
    Points : 338
    Points
    338
    Par défaut
    Tu peux mesurer le temps écoulé "à la main" avec System.nanoTime() pour te faire une idée.

    Attention par contre, ça ne mesure pas le temps consommé du CPU.

  5. #5
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 607
    Points : 15 652
    Points
    15 652
    Par défaut
    Sachant que de toute façon la précision de System.nanoTime() est très très largement inférieure à la nanoseconde (et même bien inférieure à la millisecondes), mieux vaut compter le nombre de tours de boucle effectués en une seconde.

  6. #6
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    +1 pour la boucle infini qui bouffe tout le CPU pour pas grand chose.
    Tu va utiliser le CPU inutilement pendant ton attente C'est une boucle d'attente active !!! A éviter !


    Tu peux vérifier cela comme ceci pour avoir une approximation du nombre d'iteration en 1 secondes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	long time = System.currentTimeMillis();
    	long count = 0;
    	while (true) { // boucle infinie
    		if (System.currentTimeMillis()-time > 1000) {
    			System.out.println("count = " + count);
    			break;
    		}
    		count++;
     
    		// + ton code
    	}
    J'obtiens entre 6000 et 8000 itérations pour une secondes (avec ou sans le println() qui "ralentit" l'exécution).

    C'est beaucoup trop pour ce que tu veux faire !!!



    Tu peux utiliser un timer comme l'a indiquer Uther, ou tout simplement rajouter un petit Thread.sleep() dans ton while() (une pause d'une seconde me semble largement suffisante).




    Pour en revenir à ton problème : c'est spécifique aux systèmes Windows qui bloquent l'accès au fichier pendant leur copie.
    La particularité vient du fait que l'on a accès aux infos du fichiers mais qu'on récupère un FileNotFoundException malgré que le fichier existe bien...

    Je pense que la meilleure solution serait d'ignorer cette exception afin de tenter de relire le fichier lors de l'itération suivante (s'il est fini de copier), et ainsi de suite...


    a++

    PS : Et attention également à bien utiliser les try/finally pour libérer les ressources !!!

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    Points : 85
    Points
    85
    Par défaut
    Bonsoir, en effet je voulais vous dire que je n'arrive encore pas à résoudre mon problème logiquement pour le résoudre il faut s'assurer de la copie du fichier sur le disque comment faire ?

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Points : 88
    Points
    88
    Par défaut
    Pour comparer les deux fichiers tu peux déjà commencer par comparer leurs tailles, puis tu compares le source et le destination, octet par octet.

  9. #9
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 607
    Points : 15 652
    Points
    15 652
    Par défaut
    Sauf que comme déjà expliqué au dessus, le fichier en cours de copie a déjà une taille identique au fichier d'origine et sa lecture provoque une erreur.
    J'ai essayé ma proposition (verrouiller le fichier) mais il semblerait que les fichiers en cour de copie ne soient pas verrouillés en écriture contrairement à ce que j'avais supposé.

    Il ne reste donc que la solution d'adiGuba de valable: ne rien faire tant que la lecture provoque une exception. Ce n'est pas propre, mais je ne vois pas de meilleure solution.

  10. #10
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Uther Voir le message
    Ce n'est pas propre, mais je ne vois pas de meilleure solution.
    Ce n'est pas si "sale" que cela !

    Je ne peux pas lire le fichier j'attend plus tard de pouvoir le faire...


    a++

  11. #11
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Points : 88
    Points
    88
    Par défaut
    Si, catcher une exception et la "cacher' je suis assez d'accord avec Uther c'est loin d'être une best practice...
    Désolé Uther j'ai lu ça un peu tôt ce matin mon cerveau avait pas dû tout bien assimiler.
    En revanche ce que l'on peut faire aussi c'est calculer un temps approximatif de copie en fonction du processeur et mettre un sleep là-dessus, mais bon ça ne doit pas être évident...

  12. #12
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Rastafire Voir le message
    Si, catcher une exception et la "cacher' je suis assez d'accord avec Uther c'est loin d'être une best practice...
    Pourquoi ???

    Citation Envoyé par Rastafire Voir le message
    En revanche ce que l'on peut faire aussi c'est calculer un temps approximatif de copie en fonction du processeur et mettre un sleep là-dessus, mais bon ça ne doit pas être évident...
    Comment ? Surtout que la copie ne dépend pas du processeur mais de plusieurs autres critères... et de toute manière tu n'obtiendras qu'une approximation qui t'obligera à traiter l'exception... pour en faire quoi ???


    a++

  13. #13
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Points : 88
    Points
    88
    Par défaut
    Je sais pas je pensais que ça pouvait être une piste simplement ^^.
    En revanche oui cacher des exceptions c'est plutôt à éviter, elles sont là pour détecter une anomalie dans le programme et c'est pas juste pour nous embêter qu'elles ont été mises en place, donc même si cela est parfois incontournable, lorsque l'on peut éviter de catcher une exception pour ne rien en faire il vaut mieux éviter, afin d'avoir le bon comportement dans l'ensemble du programme et bien maîtriser toutes les parties du code.

  14. #14
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Non les exceptions sont là pour signaler un problème. Si tu n'as pas de traitement spécifique en effet il ne faut pas la catcher.

    Ici on peut gérer le problème : on a un FileNotFoundException alors que le fichier existe réellement puisqu'il nous vient de la méthode list(). D'après la doc cela survient lorsque le fichier est inaccessible. Donc je ne vois pas de raison qui interdirait de traiter ce cas là...


    a++

  15. #15
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 607
    Points : 15 652
    Points
    15 652
    Par défaut
    Citation Envoyé par adiGuba
    Ce n'est pas si "sale" que cela !
    Certes, surtout que si on se limite a une lecture par seconde, le temps de génération du stacktrace ne sera pas genant. Mais je trouve dommage d'avoir a attaquer la lecture pour s’apercevoir que c'est impossible.

    Citation Envoyé par Rastafire
    En revanche oui cacher des exceptions c'est plutôt à éviter, elles sont là pour détecter une anomalie dans le programme et c'est pas juste pour nous embêter qu'elles ont été mises en place, donc même si cela est parfois incontournable, lorsque l'on peut éviter de catcher une exception pour ne rien en faire il vaut mieux éviter, afin d'avoir le bon comportement dans l'ensemble du programme et bien maîtriser toutes les parties du code.
    Catcher les exception inatendues constitue en effet une mauvaise pratique. Mais catcher une exception attendue pour adapter le fonctionnement en conséquence ne l'est pas du tout, bien au contraire.

  16. #16
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Points : 88
    Points
    88
    Par défaut
    Merci pour ces précisions, mais si le même comportement est généré par une action inattendue, il n'y aura pas moyen de le savoir, donc je pense que c'est tout de même à éviter tant que faire se peut.

    Après il est vrai que je l'ai parfois fait moi aussi puisqu'il m'est arrivé de tomber sur le même genre de problème, mais je pensais que c'était moi qui avait "mal" fait, je suis donc rassuré de savoir que je ne suis pas si mauvais que ça .

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    Points : 85
    Points
    85
    Par défaut
    Tout d'abord merci pour vos réponses, en effet adiGuba j'ai pas bien compris votre solution ignorer une exception ? Ok mais comment faire ?

  18. #18
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2011
    Messages
    65
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2011
    Messages : 65
    Points : 88
    Points
    88
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     try { 
                     //traitement 
                       ...
                     }
               catch (FileNotFoundException e) {
                    // ne rien faire :)
                     }
    Là tu attrapes l'exception pour ne rien en faire, donc tu la caches

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

Discussions similaires

  1. Problème lors de l'envoi du programme
    Par adri13 dans le forum VB.NET
    Réponses: 14
    Dernier message: 17/12/2012, 18h29
  2. Problème lors de l'envoi de données via laision RS 232
    Par Rastaforien dans le forum Langage
    Réponses: 9
    Dernier message: 26/06/2008, 11h54
  3. problème lors de l'envoi d'un formulaire
    Par fk04 dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 15/04/2007, 21h00
  4. Problème lors de l'envoi d'un mail
    Par ricki dans le forum ASP
    Réponses: 3
    Dernier message: 15/11/2006, 21h54
  5. Problème lors de l'envoie d'un mail (JavaMail)
    Par Invité dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 09/05/2006, 10h23

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