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 :

Copie efficace et rapide d'un fichier jpeg dans une autre destination


Sujet :

Entrée/Sortie Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 24
    Points : 21
    Points
    21
    Par défaut Copie efficace et rapide d'un fichier jpeg dans une autre destination
    Bonjour,

    Le sujet que je propose a déjà été vu mainte fois je pense car j'ai trouvé beaucoup de chose sur internet, le problème c'est que la seule méthode que j'ai trouvé qui avait fonctionné c'était de lire et d'écrire byte par byte.

    Ça fonctionnait certes mais c'était particulièrement lent. La finalité de ma fonction c'est de renseigner un répertoire à l'appli qui en copie tout le contenu (qui ne sera constitué que d'images) pour les mettre dans un répertoire d'un serveur distant.

    Pour l'instant l'histoire du serveur distant n'a pas d'importance, je bosse en local sur windows 7 avec des path en dur...

    Donc mon problème en fait c'est qu'une image met une dixaine de seconde à être copiée (j'exagère à peine) en lisant et écrivant byte par byte. Comment gagner du temps dessus ? J'pense que ma méthode n'est pas la bonne en fait... Je vous montre mon code :

    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
     
             String test = parametres.Parametres.DOSSIERPHOTO;
    	 File monRep = new File(test);
    	 File[]listePhoto = monRep.listFiles();
     
    	 for (int i=0;i<listePhoto.length;i++)
    	 {
     
    	 try {
    	 FileInputStream monEntre = new FileInputStream(listePhoto[i]);
    	 FileOutputStream maSortie = new FileOutputStream(test+
                                         "\\test\\"+listePhoto[i].getName());
    	 while (true)
    	 {
    		 int b = monEntre.read();
    		 if (b == -1) 
    		 {
    	    	 	break;
    		 }
    		 maSortie.write(b);
    	 }
    	 monEntre.close();
    	 maSortie.close();
     
    	 }
    Voilà donc ça ça marche mais pas du tout assez vite... En fait je me demande si c'est pas à cause de l'échange qui n'est pas du tout assez optimisé, le fait de lire et d'écrire caractère par caractère... est ce que ça ne serait pas plus rapide de mettre dans une liste ou un tableau les bytes quand on les lit et de dépiler pour écrire ? en faisant fichier par fichier plutôt que d'utiliser les flux sans arrêt par alternance non ?

    Désolé j'avais jamais vu java io avant mais là j'en ai besoin pour faire une appli pour un pote

    Merci !

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Dans le JDK 7, il y a Files.copy(), qui élude enfin ce genre de questions.

    Dans les précédentes, versions, par contre :

    En fait je me demande si c'est pas à cause de l'échange qui n'est pas du tout assez optimisé, le fait de lire et d'écrire caractère par caractère... est ce que ça ne serait pas plus rapide de mettre dans une liste ou un tableau les bytes quand on les lit et de dépiler pour écrire ? en faisant fichier par fichier plutôt que d'utiliser les flux sans arrêt par alternance non ?
    Voilà.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    byte[] buffer = new byte[4096];
     
    int nbRead = inStream.read(buffer);
    while(nbRead > 0) {
      // Attention, read() ne remplit pas le buffer entièrement,
      // tout dépend des caches de lecture.
      // Il faut n'écrire que ce qui a été lu.
      outStream.write(buffer, 0, nbRead);
      nbRead = inStream.read(buffer);
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 24
    Points : 21
    Points
    21
    Par défaut
    Salut Thelvin, merci pour ta réponse ! Donc la taille du tableau de byte est nécessairement choisie de façon arbitraire ?

    En tout cas je suis sous éclipse avec jdk 6, je ne sais pas si il est possible d'installer les bibliothèques du 7 (je ne suis pas super calé la dedans faut dire ni même dans la programmation en général d'ailleurs )



    Bref, quoi qu'il en soit ta solution avec le simple tableau de byte qui joue le rôle de tampon va peut être 100 fois plus vite que la mienne (au moins...) donc merci en plus j'aurais du voir qu'il existait un constructeur avec un tableau de byte. Le seul truc qui me gène un peu c'est la taille du tableau (je me suis tellement bouffé d'exception outOfRange dans ma courte vie de développeur

    Bref merci !

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Marginataman Voir le message
    Salut Thelvin, merci pour ta réponse ! Donc la taille du tableau de byte est nécessairement choisie de façon arbitraire ?
    Oui mais bon, le but c'est de ne pas y aller un par un. La taille du tableau, du moment qu'on peut y stocker une tétrachiée, hein...

    Citation Envoyé par Marginataman Voir le message
    en plus j'aurais du voir qu'il existait un constructeur avec un tableau de byte.
    Ce n'est pas un constructeur, c'est une méthode.

    Citation Envoyé par Marginataman Voir le message
    Le seul truc qui me gène un peu c'est la taille du tableau (je me suis tellement bouffé d'exception outOfRange dans ma courte vie de développeur
    read() ne lira jamais plus que ton tableau ne peut en contenir. Il peut en lire moins, mais pas plus.
    Et par conséquent, si tu n'écris avec write() que le nombre d'octets qui a été lu par read(), ça ne dépassera pas non plus. Logique.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 24
    Points : 21
    Points
    21
    Par défaut
    Ah okay ! Merci ;-)

  6. #6
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 943
    Points
    5 943
    Par défaut
    Je rajouterais qu'on peut encapsuler le InputStream dans un BufferedInputStream ce qui peut améliorer les perfs .
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  7. #7
    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,

    Citation Envoyé par le y@m's Voir le message
    Je rajouterais qu'on peut encapsuler le InputStream dans un BufferedInputStream ce qui peut améliorer les perfs .
    Oui et non... ca dépend.

    Le BufferedInputStream est intéressant à partir du moment où tu va lire les données par "petit bout" ou byte par byte...

    Si tu fait déjà une lecture bufférisé, c'est inutile de rajouter un second buffer...


    a++

  8. #8
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 943
    Points
    5 943
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Salut,



    Oui et non... ca dépend.

    Le BufferedInputStream est intéressant à partir du moment où tu va lire les données par "petit bout" ou byte par byte...

    Si tu fait déjà une lecture bufférisé, c'est inutile de rajouter un second buffer...


    a++
    Le pire c'est qu'instinctivement c'est toujours ce que je me suis dit sans prendre le temps de confirmer .
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 24
    Points : 21
    Points
    21
    Par défaut
    Je ne comprends pas bien l'intérêt du bufferedInputStream du coup :/ faudra que je vois les méthodes qu'on a avec... bon dans mon cas de toute façon à priori ça sert pas c'est juste par curiosité

    En tout cas merci , par contre je viens de me rendre compte que mon post avait d'avantage sa place dans API>IO, j'avais pas vu, désolé !

  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 Marginataman Voir le message
    Je ne comprends pas bien l'intérêt du bufferedInputStream du coup :/ faudra que je vois les méthodes qu'on a avec... bon dans mon cas de toute façon à priori ça sert pas c'est juste par curiosité
    Cela ne sert pas dans ton cas précis...

    Ce qui "coûte" cher c'est les accès IO, car cela implique des ressources géré par l'OS. En utilisant un buffer tu diminues le nombre d'accès ce qui est plus performant...


    Maintenant tu peux être amené à vouloir lire un fichier byte par byte. Par exemple afin de décoder un header ou autre...

    Dans ce cas le BIS est utile car il va gérer le buffer à ta place, et donc diminuer les accès IO. La majorité de tes read() se feront dans le buffer sans accès IO, de manière totalement transparente :-)

    En tout cas merci , par contre je viens de me rendre compte que mon post avait d'avantage sa place dans API>IO, j'avais pas vu, désolé !
    Déplacé ;-)

    a++

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 24/02/2009, 09h05
  2. Enregistrement de fichier "distants" dans une autre version d'Excel (95)
    Par bravojr dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 08/10/2008, 17h00
  3. Réponses: 2
    Dernier message: 06/12/2006, 12h14
  4. [C#] Ouvrir un fichier PDF dans une autre fenetre
    Par ZePostman dans le forum ASP.NET
    Réponses: 3
    Dernier message: 15/03/2006, 13h41
  5. Copie de fichiers XLS dans une table
    Par sebvita dans le forum Oracle
    Réponses: 3
    Dernier message: 28/12/2005, 09h13

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