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

Concurrence et multi-thread Java Discussion :

Multi threading et BlockingQueue


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut Multi threading et BlockingQueue
    Bonjour, je travaille sur un programme de recherche de mots

    Le programme cherche dans les fichiers d'un répertoire et de ses sous-répertoire et affiche les lignes qui contiennent le mot spécifié.

    La Synchronisation est assurée par l'utilisation d'une queue de blocage qui contrôle un ensemble de threads.

    Tout se passe bien si la recherche est effectuée ds un répertoire qui contient un nombre de sous répertoires et de fichiers limités

    Si je tente l'opération sur un répertoire très vaste , le programme se bloque après un trentaine de secondes et je dois redémarrer Eclipse

    Une Explication ? Peut-être un nombre de threads (100) trop élevé ??

    Merci de votre concours, Voici le 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
    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
    90
    91
    92
    93
    94
    95
    96
     
    package thread;
     
    import java.io.*;
    import java.util.*;
    import java.util.concurrent.*;
     
    public class QueueDeBlocage {
    private static final int THREADS_DE_RECHERCHE = 100;
    private static String répertoireDeBase;
     
    public static void main(String[] args) {      
     Scanner clavier = new Scanner(System.in);
     
     System.out.print("Le Dossier de la recherche : ");
     répertoireDeBase = clavier.nextLine();
     
     System.out.print("Le mot à rechercher : ");
     String motDeRecherche = clavier.nextLine();
     
    BlockingQueue<File> queue = new LinkedBlockingQueue<File>();
     
     EnumérationFichiers fichiers = new EnumérationFichiers(queue, new File(répertoireDeBase));
     new Thread(fichiers).start();
     for (int i = 1; i <= THREADS_DE_RECHERCHE; i++)
        new Thread(new TâcheDeRecherche(queue, motDeRecherche)).start();
    }
    }
     
    class EnumérationFichiers implements Runnable {
    private BlockingQueue<File> queue;
    private File répertoire;
    public static File VIERGE = new File("");
     
    public EnumérationFichiers(BlockingQueue<File> queue, File répertoire) {
     this.queue = queue;
     this.répertoire = répertoire;
    }
     
    public void run() {
     try {
        énumère(répertoire);
        queue.put(VIERGE);
     }
     catch (InterruptedException e) {}
    }
     
    public void énumère(File répertoire) throws InterruptedException {
     File[] fichiers = répertoire.listFiles();
     for (File fichier : fichiers) {
         if (fichier.isDirectory()) énumère(fichier);
         else {
            queue.put(fichier);
            System.out.printf("Lecture du fichier %s\n", fichier.getPath());
         }
     }
    }
    }
     
    class TâcheDeRecherche implements Runnable {
    private BlockingQueue<File> queue;
    private String mot;
     
    public TâcheDeRecherche(BlockingQueue<File> queue, String mot) {
     this.queue = queue;
     this.mot = mot;
    }
     
    public void run() {
     try {
        boolean fini = false;
        while (!fini) {
           File fichier = queue.take();
           if (fichier == EnumérationFichiers.VIERGE) {
              queue.put(fichier);
              fini = true;
           }
           else recherche(fichier);
        }
     }
     catch (IOException e) { e.printStackTrace(); }
     catch (InterruptedException e) { }
    }
     
    public void recherche(File fichier) throws IOException {
     Scanner lecture = new Scanner(new FileInputStream(fichier));
     int nombreLigne = 0;
     while (lecture.hasNextLine()) {
        nombreLigne++;
        String ligne = lecture.nextLine();
        if ( (ligne.contains(mot.toLowerCase())) || (ligne.contains(mot.toUpperCase()))) 
           System.out.printf("%s:%d:%s%n", fichier.getPath(), nombreLigne, ligne);
     }
     lecture.close();
    }
    }

  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
    C'est sûr que 100 threads c'est un peu exagéré, dans des conditions classiques on en mettra plutôt de 2 à 5 : nombre de processeurs plus 1.
    Mais ici, à la base, c'est le fait même d'avoir plusieurs threads qui ne sert à rien : de toute façon il n'y a qu'un seul disque dur et il ne peut pas travailler en parallèle (je suppose que ça peut marcher si le contenu a été intégralement chargé en cache, mais le premier passage qui s'est occupé de charger ça en cache est quand même bien stressant.)

    Ceci étant dit, il y a trop de threads, mais ce n'est pas une raison pour que ça bloque.

    Pour l'instant la seule chose que je vois, c'est que dès qu'un thread tombe sur VIERGE, il le remet dans la liste et s'arrête. Du coup, il devient possible pour tous les threads de tomber dessus et s'arrêter, alors que le thread d'énumération tourne encore, et finit par manquer de place pour insérer de nouveaux fichiers dans la queue, bloquant indéfiniment dans le put().
    Cette méthode d'arrêt n'est donc pas fiable. Mais ça me semble un peu gros quand même.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut Bonjour Thelvin
    J'ai puisé cet exemple à l'adresse suivante

    http://manu.kegtux.org/Java/Tutoriel...et/Threads.htm

    Comme j'avais le problème évoqué ci dessus, je l'ai modifié en remplaçant

    BlockingQueue<File> queue = new ArrayBlockingQueue<File>(TAILLE_QUEUE);

    proposé au départ par

    BlockingQueue<File> queue = new LinkedBlockingQueue<File>();

    qui ne pose pas de problème de capacité mais cela n'a rien changé

    En réféchissant à ton explication , je pense qu'il faut terminer le thread de parcours de l'arborescence du répertoire (le premier thread) avant de lancer

    l'armada des threads de recherche . Je propose donc d'utiliser un join() comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    EnumérationFichiers fichiers = new EnumérationFichiers(queue, new File(répertoireDeBase));
     
        Thread th = new Thread(fichiers).start();
        th.join();
        for (int i = 1; i <= THREADS_DE_RECHERCHE; i++)
          new Thread(new TâcheDeRecherche(queue, motDeRecherche)).start();
    Je voudrais avoir ton avis avant de tester car j'ai du redémarrer complètement l'ordi à plusieurs reprises à cause du blocage

    Merci de ton aide coutumière

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Moi ce que je vois surtout, c'est plein de bazard comme ça

    catch (InterruptedException e) {}

    Alors la promière chose à faire c'est d'arrêter d'ignorer des exception. Soit tu les traites (message d'erreur, nettoyage, etc) soit tu les fais remonter plus haut. En l'occurence un InterruptedException qui remonte de ton enumère() empêchera de mettre VIERGE dans la liste et donc empechera les thread de s'arrêter.

    => profite en pour mettre la condition d'arrêt dans un bloc finally.

    Pas besoin de redémarrer eclipse parce que ton programme plante. Y a une petit croix à droite de la console de ton programme pour le tuer. Si eclipse rame comme un pété, soit t'es occupé de bouffer toute la mémoire vive avec ton programme, soit t'es occupé de tellement flooder la console qu'il n'arrive plus à la traiter.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut Rebonjour
    J'ai tenu compte des remarques précedentes

    J'ai placé un join() afin de terminer l'énumération des fichiers avant de commencer la recherche du mot

    mais je me trouve confronté au meme problème . Comme dit Tchize, on dirait que la console est noyée. Si je veux stopper le déroulement, l'écran blanchit et parfois je suis obligé de redémarrer complètement la machine

    Faut-il le tester autrement que par la console d'Eclipse

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Si ta console est noyée, tu peux déjà regarder dans eclipse si tu a bien défini une taille limite. Si tu as marqué "pas de limite" à la taille de ta console et que ton programme génère en 1 seconde 1G de messages, je te laisse évaluer le problème Personellement, j'ai tendance à limiter à 10.000 lignes la console, c'est bien assez pour revenir en arrière

    Tu peux aussi lancer ton programme en debug et faire du pas à pas pour voir où il coince.

    La queue sans limite ainsi que le join, ce n'est pas une bonne idée. Si on utilise une BlockingQueue, c'est justement pour la limiter et avoir producteur et consommateur qui tournent en même temps.

    Il n'y a pas de raison de redémarrer l'ordi, dans le pire des cas, tu tue tes process java avec le taskmanager.

    Et n'oublie pas ma remarqe à propos des exceptions!

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut
    Afin de voir si la console Eclipse est responsable, j'ai transformé le programme en .jar et je l'ai lancé depuis la console DOS

    Tout est OK pour le parcours de l'arborescence mais par la suite lors de la recherche de mots ds les fichiers, çà foire et il devient impossible de fermer la console DOS

    J'ai réduit le nombre de threads de recherche de 100 à 10 ... peut etre est-ce encore trop ou est-ce la méthode de recherche de mots qui ne convient pas

    Dans mon répertoire cible (là où je cherche un fichier qui contient le mot en question) , il y a de tout : du texte , des images, ...
    et la méthode de recherche de mot se base sur
    Scanner lecture = new Scanner(new FileInputStream(fichier));

    çà coince peut-être là ???

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    T'as quoi comme machine? Il n'est pas impossible que ton application mette l'Os sous les genoux au niveau des IOs

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut Configuration
    Config machine : Intel (r) CORE (TM)2 Quad CPU 2,33 Ghz 2,34 Ghz
    RAM : 4 G
    OS : 32 bit
    WINdows 7 integral

    Le dossier ds lequel je fais les recherches se trouve :
    C:\Users\Utilsateur\Dossierenquestion

    Caractéristiques de ce Dossierenquestion : de tout : images , pdf, fichiers
    texte, zip, ...

    Contenu : 29569 fichiers 2704 Dossiers Taille 7,74 Go

    Voila, je crois que c'est assez complet

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Essaie déjà de réduire à 1 thread pour voir si les IOs sont le problème. Comme on l'a dit, faire du multithreading + IOs ce n'est pas une bonne idée

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut réduire à 1 thread
    J'ai donc réduit à 1 thread

    Le comportement est le suivant : après avoir parouru l'arborescence sans problème, il commence la recherche à l'intérieur des fichiers
    Cette recherche est rapide au départ puis des temps morts de + en + long et
    le processus semble à l'arrêt ??

    Différence par rapport au mutithreading : je peux stopper proprement le processus en fermant la console DOS

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    a quoi tu vois les temps morts? Ton programme n'affiche que les lignes trouvées.

    Le temps mort de plus en plus long indiquent en général un manque de mémoire pour ton application et donc un garbage collector qui a de plus en plus de travail à faire. Ca finit au bout d'un certain temps par un OutOfMemoryException.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut a quoi tu vois les temps morts?
    Exact il ne devrait afficher que les lignes trouvées et pourtant il affiche
    continuellement le contenu des fichiers examinés

    Au bout de 10 minutes de pause (plus de défilement) et poutant je suis à l'intérieur d'un fichier (je n'ai pas terminé la recherche), je considère que le processus est "mort" et je ferme la console DOS

  14. #14
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Je vois que tu utilise un scanner et sa méthode nextLine pour lire tes fichiers. Mauvaise idée. Si t'as un fichier de plusieurs centaines de M sans retour à la ligne, ton application va tenter de tout bufferiser en mémoire.
    Tu devrais convertir ta chaine à rechercher en byte[] et parcourir tes inputstream jusqu'à trouver les byte[] en question.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut convertir ta chaine à rechercher en byte[] et parcourir tes inputstream jusqu'à trouver les byte[] en question
    Rebonjour,

    J'ai converti en byte[] les inputSream et effectué la recherche comme conseillé ds post précédent

    Meme comportement que précédemment mais cette fois j'ai un message d'erreur
    quand çà bloque

    Exception in thread "Thread-1" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
    at thread_Kegtux_3.TransformerByte.getBytes(QueueDeBlocage.java:177)
    at thread_Kegtux_3.TÔcheDeRecherche.recherche(QueueDeBlocage.java:135)
    at thread_Kegtux_3.TÔcheDeRecherche.run(QueueDeBlocage.java:110)
    at java.lang.Thread.run(Thread.java:662)

    Test effectué depuis console DOS avec un seul trhead

  16. #16
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Tu ne serais pas occupé d'essayer de lire tout le fichier d'un coup par hasard? Il faut le lire bloc par bloc, impossible de faire tenir un fichier de plusieurs G en mémoire

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut code + plan
    Re,

    Je transmet le code modifié et je joins un petit plan
    pour s'y retrouver plus vite

    Plan

    - QueueDeBlocage : la class principale + main

    - EnumérationFichiers : le thread principal

    - TâcheDeRecherche : le THREADS_DE_RECHERCHE

    methode : recherche()

    class TransformerByte
    class TrouverMot

    methode read()

    La classe TrouverMot permet de trouver le mort recherché et de le remplacer par un autre

    Mais ceci n'étant pas le sujet , j'ai adapté cette classe en fonction
    et j'ai laissé pour le futur le reste
    en supprimant ce qui pourrait interférer dans la bon déroulement du programme.

    Je rappelle que l'énumération se déroule sans problème
    La recherhe fonctionne quelques minutes et puis se bloque sur des repertoires tres imposants


    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
     
    package ajeter;
     
    // Tu devrais convertir ta chaine à rechercher en byte[]
    // et parcourir tes inputstream jusqu'à trouver les byte[] en question.
     
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FilterInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.Scanner;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
     
    public class QueueDeBlocage {
     
    	public static void main(String[] args) throws InterruptedException {      
    	   String répertoireDeBase;
    	   final int THREADS_DE_RECHERCHE = 1; 
     
    	   Scanner clavier = new Scanner(System.in);
    	   System.out.print("Le Dossier de la recherche : ");
    	   répertoireDeBase = clavier.nextLine();
    	   System.out.print("Le mot à rechercher : ");
    	   String motDeRecherche = clavier.nextLine();
     
    	   BlockingQueue<File> queue = new LinkedBlockingQueue<File>();
     
    	   EnumérationFichiers fichiers = new EnumérationFichiers(queue, new File(répertoireDeBase));
    	   Thread th = new Thread(fichiers);
    	   th.start();
    	   th.join();
     
    	   System.out.println("Enumération terminée");
    	   System.out.println("--------------------");
     
    	   for (int i = 1; i <= THREADS_DE_RECHERCHE; i++)
    	      new Thread(new TâcheDeRecherche(queue, motDeRecherche)).start();
    	}
    }
     
    class EnumérationFichiers implements Runnable {
    	private BlockingQueue<File> queue;
    	private File répertoire;
    	public static File VIERGE = new File("");
     
    	public EnumérationFichiers(BlockingQueue<File> queue, File répertoire) {
    	   this.queue = queue;
    	   this.répertoire = répertoire;
    	}
     
    	public void run() {
    	   try {
    	      énumère(répertoire);
    	      queue.put(VIERGE);
    	   }
    	   catch (InterruptedException e) {
    		  System.out.println("Erreur dans EnumérationFichiers ");
    	   }
    	}
     
    	public void énumère(File répertoire) throws InterruptedException {
    	   File[] fichiers = répertoire.listFiles();
    	   for (File fichier : fichiers) {
    	       if (fichier.isDirectory()) énumère(fichier);
    	       else {
    	          queue.put(fichier);
    	          System.out.printf("Lecture du fichier %s\n", fichier.getPath());
    	       }
    	   }
    	}
    }
     
    class TâcheDeRecherche implements Runnable {
    	private BlockingQueue<File> queue;
    	private String mot;
     
    	public TâcheDeRecherche(BlockingQueue<File> queue, String mot) {
    	   this.queue = queue;
    	   this.mot = mot;
    	   }
     
    	public void run() {
    	   try {
    	      boolean fini = false;
    	      while (!fini) {
    	         File fichier = queue.take();
    	         if (fichier == EnumérationFichiers.VIERGE) {
    	            queue.put(fichier);
    	            fini = true;
    	         }
    	         else recherche(fichier);
    	      }
    	   }
    	   catch (IOException e) { e.printStackTrace(); }
    	   catch (InterruptedException e) { }
    	}
     
     
    	public void recherche(File fichier) throws IOException {
    	    InputStream is = new FileInputStream(fichier);
    	    TransformerByte tByte = new TransformerByte();
    	    byte [] conversion = tByte.getBytes(is);
     
            ByteArrayInputStream bis = new ByteArrayInputStream(conversion);
     
            byte[] search = mot.getBytes();
            byte[] replacement = mot.getBytes();
     
     
            InputStream ris = new TrouverMot(bis, search,replacement);        
     
            int b;
            while (-1 != (b = ris.read()))
            {
            	if (b == -2)
            	{
            		System.out.print(fichier.getPath());
            		System.out.println("   : MOT TROUVE");
            		System.out.println();
            		System.out.println();
            		break;
            	}        	
            }
            ris.close();
    	}
    }
     
    class TransformerByte {
     
    	  public byte[] getBytes(InputStream is) throws IOException {
     
    	    int len;
    	    int size = 1024;
    	    byte[] buf;
     
    	    if (is instanceof ByteArrayInputStream) {
    	      size = is.available();
    	      buf = new byte[size];
    	      len = is.read(buf, 0, size);
    	    } else {
    	      ByteArrayOutputStream bos = new ByteArrayOutputStream();
    	      buf = new byte[size];
    	      while ((len = is.read(buf, 0, size)) != -1)
    	        bos.write(buf, 0, len);
    	      buf = bos.toByteArray();
    	    }
    	    return buf;
    	  }
    }
     
    class TrouverMot extends FilterInputStream {
     
        LinkedList<Integer> inQueue = new LinkedList<Integer>();
        LinkedList<Integer> outQueue = new LinkedList<Integer>();
        final byte[] search, replacement;
     
        protected TrouverMot(InputStream in, byte[] search, byte[] replacement) {
            super(in);
            this.search = search;
            this.replacement = replacement;
        }
     
        private boolean isMatchFound() {
            Iterator<Integer> inIter = inQueue.iterator();
            for (int i = 0; i < search.length; i++)
                if (!inIter.hasNext() || search[i] != inIter.next())
                    return false;
            return true;
        }
     
        private void readAhead() throws IOException {
            while (inQueue.size() < replacement.length) {
                int next = super.read();
                inQueue.offer(next);
                if (next == -1)
                    break;
            }
        }
     
     
        @Override
        public int read() throws IOException {
     
            if (outQueue.isEmpty()) {
     
                readAhead();
     
                if (isMatchFound()) {
                    for (int i = 0; i < search.length; i++)
                        inQueue.remove();
     
                    //for (byte b : replacement)
                        //outQueue.offer((int) b);
                        outQueue.offer((int) -2);
     
     
                } else
                    outQueue.add(inQueue.remove());
     
            }
     
            return outQueue.remove();
        }
     
    }

  18. #18
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Lors du blocage, est-ce que tu as à l'écran "Enumération terminée" ? (je suppose que oui)

    Affiche au fur et à mesure le nom du fichier que tu lit. Si ça tombe, c'est toujours le même dossier / les mêmes fichier qui bloqunte et c'est juste l'OS qui te bloque car il l'a vérouillé. C'est une information capitale


    Ta méthode de scan ne fait effectivement rien à part lire byte par byte pour le moment. La manière dont tu lit dans TransformerByte sera la bonne, restera bien sur à mettre en place le code cherchant ton byte[] dans un autre byte[] ou pire à cheval sur deux byte[] successifs

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    315
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 315
    Points : 114
    Points
    114
    Par défaut Si ça tombe, c'est toujours le même dossier / les mêmes fichier qui bloqunte
    Exact Tchize, c'est bien le meme fichier qui bloque

    Voici le message (meme que précedent) avec le nom du fichier bloquant

    C'est un fichier .iso

    Normal que çà bloque ???

    Fichier LU : C:\Users\Utilisateur\JAVA\UML\dvdUML.isoException in thread "Thread-
    1" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2786)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
    at thread_Kegtux_3.TransformerByte.getBytes(QueueDeBlocage.java:200)
    at thread_Kegtux_3.TÔcheDeRecherche.recherche(QueueDeBlocage.java:158)
    at thread_Kegtux_3.TÔcheDeRecherche.run(QueueDeBlocage.java:132)
    at java.lang.Thread.run(Thread.java:662)

  20. #20
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Je viens de regarder en détail ton TransformerByte, je ne devais pas avoir les yeux en face des trous hier. Il est très mal implémenté puisqu'il charge tout le fichier en mémoire et que ce n'est pas possible pour les gros fichiers!

    Tu ne peux pas te permettre d'avoir tout le fichier en mémoire, il faut le lire bloc par bloc, par exemple 1k ou 100k à la fois et traiter chaque bloc au fur et à mesure pour ta recherche.

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. Réponses: 2
    Dernier message: 15/05/2004, 18h33
  3. Réponses: 16
    Dernier message: 30/01/2004, 11h05
  4. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  5. [Kylix] exception qtinft.dll et multi-threading
    Par leclaudio25 dans le forum EDI
    Réponses: 3
    Dernier message: 27/03/2003, 18h09

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