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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    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
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    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 698
    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 confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    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 très actif
    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
    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
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 698
    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 698
    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
    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,


    +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 confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : Tunisie

    Informations forums :
    Inscription : Août 2006
    Messages : 193
    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 actif
    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
    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.

+ 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