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

AWT/Swing Java Discussion :

JTextPane : Affichage de gros fichiers texte


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut JTextPane : Affichage de gros fichiers texte
    Bonjour à tous,

    Depuis deux jours je suis confronté à une erreure OutOfMemomryError lors de l'appel de la méthode setText() d'un JTextPane (voir exemple simplifié ci-dessous).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    JTextPane editor;
    String str;
     
    // code de traitement ...
     
    editor.setText(str);
     
    // code de traitement ...
    La variable str est initialisée avec le contenu d'un fichier texte. Je ne développe pas plus le code car cette partie ne pose pas de problème.

    Seulement, lorsque le fichier ouvert dépasse environ 2Mo, j'obtiens l'erreure OutOfMemoryErreur sur la méthode setText().

    J'ai alors fait l'essai de lire le fichier ligne par ligne et d'ajouter les lignes une à une dans le JTextPane. Mais ça n'a strictement rien changé.

    Alors après plusieurs recherche sur le net, j'ai modifié la mémoire de la JVM avec la commande -Xmx256. Celà a réglé temporairement mon problème, car lorsque je suis passé à un fichier de 4Mo j'ai de nouveau obtenue l'erreur OutOfMemoryError.

    Je pourrais alors passer une commande -Xmx512 à la JVM mais ça repoussera le problème temporairement sans le corriger réellement.
    De plus, mon application est censée tournée sur un serveur d'applications ou une multitude de taches tournent en même temps, et je me pose des questions sur les interactions que pourrait donner une telle monopolisation de mémoire. Mais ce n'est pas l'objet de mon message ...

    J'ai donc fait un test avec un JTextArea et avec une commande -Xmx128m pour la JVM et un fichier de 4Mo, je n'ai eu aucune erreure. Malheureusement, comme j'ai besoins de "styler" le texte je ne peus pas utiliser cette classe.
    Mais ce test me prouve que c'est pas tant la taille du fichier qui apparement pose problème. 2 ou 4Mo ne sont plus de nos jour de grosses quantités de données.

    Par contre les fichiers texte que je dois afficher sont particuliers et contiennent énormément de lignes. Ils sont du type :

    OBJET1 = TOTO
    PARAM1 = XX
    ...
    PARAM20 = YYYYYY
    FIN
    OBJET2 = TUTU
    PARAM1 = ABCD
    ...
    PARAM20 = AZERTY
    FIN
    ...
    ...


    Ce qui représente de l'ordre de 300 000 lignes pour un fichier 4Mo. Et j'ai l'intime conviction que c'est ce nombre de lignes, traité differemment dans un JTextArea et un JTextPane, qui me pose problème.
    J'ai l'impression que le JTextArea ne cré qu'une seule instance d'objet pour stocker toutes les lignes, alors que le JTextPane va créer une instance d'objet par ligne. Et en fait mon problème viendrait de l'instanciation de 300 000 objets qui est beaucoup plus gourmand en mémoire.

    Pouvez-vous me dire si mon intuition est bonne ou pas ?

    Maintenant, que mon intuition soit bonne ou pas, j'aimerais trouver une autre solution technique pour afficher ces fichiers, alors toutes bonnes idées sont les bien venues. Peut être un autre composant que les JTextPane ou JEditorPane ?

    En cherchant sur le net, certains forums parlaient de "bufferiser" le fichier et d'afficher dans le JTextPane que le texte pouvant être visualisée et de raffraichir le contenu visible en fonction des déplacements de la barre de défilement du JScrollPane. Mais aucun exemple était proposé et ça me parait assez compliqué. Donc si quelqu'un a déjà testé ou mis en place une telle solution je suis preneur.

    Merci d'avance pour vos conseils, astuces ou solutions ...

  2. #2
    Membre éprouvé Avatar de Satch
    Homme Profil pro
    Hypnothérapeute - Magicien
    Inscrit en
    Mars 2004
    Messages
    500
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Suisse

    Informations professionnelles :
    Activité : Hypnothérapeute - Magicien

    Informations forums :
    Inscription : Mars 2004
    Messages : 500
    Par défaut
    Et l'afficher en plusieurs pages, ça ne pourrait pas jouer ?

    Par exemple ne mettre qu'un certain nombre de lignes, et un bouton "Suivant" pour avoir la suite du texte.

  3. #3
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    Merci Satch pour ton idée.

    C'est vrai que traiter un affichage par page avec un bouton pour se déplacer est une alternative plus simple. Mais elle me semble moins fonctionnelle aussi.
    Si je fais des pages de 1000 lignes et que l'utilisateur veut accéder à une information paumée au niveau de la 250 000 ème ligne il devra cliquer 250 fois sur "suivant" ou une fois sur "fin" et 50 fois sur "précédent". Pas très pratique ...

    Je crois que ce qu'il me faut c'est effectivement un affichage par page mais en gardant le défilement via la scrollbar. Et là, tu me donnes de nouvelles perspective car je n'avais pas vu un défilement par pages mais par lignes (comme la fonction initiale du JTextPane).

    Un fichier de 300 000 lignes est composée d'environ 4000 objets. Je pourrais très bien dire qu'un objet correspond à une page et donc ainsi faire un défilement et un affichage objet par objet, ce qui reste cohérent point de vue de l'utilisateur.

    Je vais réfléchir à ton idée ...

    Mais toutes autres bonnes idées comme celle-ci sont les biens venues !

    Merci d'avance pour vos propositions ...

  4. #4
    Membre Expert
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Par défaut
    Je dis peut-être une bêtise, à confirmer :
    Il le semble que le mapping du fichier en mémoire pourrait corriger ton problème définitivement. Essais d'initialiser ton JTextPane à partir MappedByteBuffer ( package java.nio ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    FileInputStream fis=new FileInputStream("monFichier");
    FileChannel channel=fis.getChannel();
    int size=(int)channel.size();
    MappedByteBuffer buff=channel.map(FileChannel.MapMode.READ_ONLY,0,size);
    ...

  5. #5
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    Merci iohack pour le tuyau !

    Je n'y connais rien en mapping et au package java.nio mais je vais regarder ça de près.

    Je te tiens au courant et te demanderais peut être plus d'infos si je ne m'en sort pas tout seul ...

  6. #6
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    iohack,

    Je viens de regarder ton idée et je crois que je n'irai pas très loin avec cette solution pour plusieurs raisons :
    1) je ne peus pas créer le FileInputStream car le texte que je veux afficher ne viens pas d'un fichier mais d'un String.
    2) en cherchant rapidement je n'ai pas touvé un moyen simple de passer le contenu du MappedByteBuffered au JTextPane.
    3) le JTextPane aura toutes les chances de me ressortir l'erreur OUtOfMemoryError à partir du moment ou je lui envoie la même quantitée de donnée.

    Merci quand même pour ton aide ...

  7. #7
    Membre Expert
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Par défaut
    1) je te cite : "La variable str est initialisée avec le contenu d'un fichier texte"
    2) et 3) à la fois : après reflexion et relecture de la javadoc, effectivement cela risque de poser dans la mesure ou pour décoder de byte en caractère, il va y avoir alocation mémoire pour le nouveau buffer ( que ce soit une String, CharSequence, ou CharBuffer ). Cela-dit, l'utilisation de nio est plus performante.
    Conclusion : à moins que quelqun vienne nous donner le tip de la mort, la méthode par pages est à privilégier.
    PS, je rêve peut-être mais si le fonctionnement du JTextPane est basée sur des références ( poiteurs de byte ) et qu'il est capable de décoder à la volée ( en unicode 16 bits par défaut je présume ) pour l'affichage, alors il serait possible de n'utiliser aucune ressource mémoire ou presque. En tout cas, coder un composant ayant ce comportement doit être faisable, mais pas aisé ( cela revient un peu à utiliser les notions de plages en fonction de la zone affichée )...

  8. #8
    Membre éclairé Avatar de biozaxx
    Profil pro
    Inscrit en
    Août 2004
    Messages
    403
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 403
    Par défaut
    Citation Envoyé par patanoc
    J'ai l'impression que le JTextArea ne cré qu'une seule instance d'objet pour stocker toutes les lignes, alors que le JTextPane va créer une instance d'objet par ligne. Et en fait mon problème viendrait de l'instanciation de 300 000 objets qui est beaucoup plus gourmand en mémoire.
    salut,

    pour voir si tu as effectivement des instances d'objet créées as tu essayé d'utiliser un profiler (genre JProfiler , tu trouveras une version d'essai sur leur site)

    ca pourrait te donner une idée plus precise de la source du probleme !

  9. #9
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    Bonjour biozaxx,

    Pour l'instant je n'ai pas essayé de comprendre plus précisemment d'où venait le problème. Je sais simplement qu'il vient du fait de l'utilisation du JTextPane.

    J'ai donc plutôt essayé de contourner le problème en utilisant differemment ce composant avec une gestion de l'affichage par page et un buffer. Mais j'avoue que je ne m'en sort pas bien et que ça devient très compliqué pour moi (gestion des sélections, recherches, copier coller etc ...). C'est vraiment la misère et je ne vois pas du tout comment je vais pouvoir m'en sortir ...

    Simplement au cours de mes differents essais, j'ai pu constaté les choses suivantes en vérifiant la mémoire utilisée au cours du chargement de mes 300 000 lignes dans le JTextPane:
    JTextPane vide (au démarrage de mon appli) : 20 Mo utilisés.
    JTextPane chargé avant raffraichissement de l'affichage : 110 Mo utilisés.
    JTextPane chargé après raffraichissement de l'affichage : > 250 Mo utilisés. (erreur OutOfMemoryError)

    Contrairement à ce que je disais dans mon premier post, l'instanciation des 300 000 objets n'est pas en fait le vrai problème (même si ça reste très gourmand). Le problème est le raffraichissement de l'affichage du JTextPane.
    Et là, mes compétences sont largement dépassées pour que je puisse améliorer quoi que ce soit ...

    Si quelqu'un a une solution ou une idée pour me sortir de ce pétrin je lui serait très reconnaissant !

    Merci à tous

  10. #10
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    Bonjour à tous,

    Je suis désolé de persister et de relancer la discution, mais je n'arrive pas à régler mon problème seul !!!

    Est'ce que quelqu'un aurait une idée, une méthode, un tuto voir même un exemple sur le développement d'un éditeur de texte avec affichage du texte par page ou par petite partie dans un JTextPane ou autre ?

    Merci d'avance

  11. #11
    Membre Expert
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Par défaut
    J'ai fait pas mal derecherche sur ce problème lié au gros fichiers sans trop de résultats.
    Je pense qu'il faudra créer toi même un nouveau type de textpane qui ne lis qu'une partie du fichier, et en fonction des clicks sur une scrollbar associée, ou d'appuis sur les touches de déplacement, met à jour la partie affichée.
    L'idée serait en gros de prendre un buffer de 10 Mo par par exemple et de placer la vue du composant aux alentours des 5Mo, si l'utilisateur de déplace aux alentours des 9Mo ( limites paramétrée ), alors l'offset d'affichage devriendra le milieu du buffer, soit une plage de [4mo-14Mo].
    Si quelqun a d'autres idées je suis également preneur.

  12. #12
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    Merci iohack pour tes recherches.

    J'ai également fait pas mal de recherche et comme toi je n'ai pas trouvé grand chose (pour ne pas dire rien).
    Mais j'ai peut être une piste. J'utilise actuellement Netbeans pour mes développement et il me semble que leur éditeur a le fonctionnement que tu décrit (à vérifier). J'ai essayer de récupérer les sources pour vérifier, mais il y a tellement de code ( > 2000 fichiers) que j'ai abandonné.
    Mais si tu as le courage, je pense que tu peus trouver un bon exemple de ce genre d'implémentation dans Netbeans.

    Maintenant, pour mon problème, j'ai complètement repensé mon interface. Je pense mettre en place un JTree qui me listera mes 4000 objets et une JTable qui affichera le contenu de l'objet sélectionné. Avec un buffer derrière qui possède toutes les données. Je ne sais pas encore si les performances seront bonnes (surtout pour le JTree) mais je vous tiendrais au courant quand j'aurais fini mes tests.

    C'est une solution que j'avais imaginée dès le départ mais qui me demandait un temps de développement plus important qu'un simple JTextPane. Maintenant que je dois développer un JTextPane spécifique, cette solution me parait plus sure et plus rapide.
    J'avais donc fait le mauvais choix !

    Tout comme iohack Je reste toujours très interressé par toutes autres idées ou propositions ...

  13. #13
    Membre averti
    Inscrit en
    Novembre 2006
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 31
    Par défaut
    Bonjour à tous,

    Après une semaine de vacance, j'ai testé la solution du JTree + JTable, et celle-ci me convient très bien.
    Le temps de chargement est identique à celui du JTextPane (environ 10 sec) mais au niveau mémoire cette solution est bien meilleure. 70Mo seulement contre plus de 256Mo avec le JTextPane (pour un fichier de 2Mo 350000 lignes représentant 4000 objets).

    Je conseille donc cette solution à tous ceux qui ont un gros fichier à éditer et qui peuvent le décomposer en objets (parties de texte de même structure et répétitives).

    Je laisse volontairement ce message ouvert car la solution que j'utilise ne pourra pas répondre à toutes les situations et que j'ai détourné le problème en utilisant d'autres composants.

    L'utilisation du JTextPane avec de gros fichier de plus de 300 000 lignes n'a toujours pas de solution ...

    Je suis toujours preneur d'une solution avec un JTextPane ...

    Merci à tous !

  14. #14
    Membre Expert
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Par défaut
    J'ai toujours l'idée de développer un composant hérité du JTextPane limité d'un point de vue mémoire car jouant sur des buffers, plus ça va et plus j'imagine comment. Je dis bien "imagine" car pas encore lancé dans le développement, je suis en ce moment sur la conception d'un éditeur hexadécimal évolué mais qui lui fonctionne par page ( la taille de la page est le nombre d'octets affichable dans le TextPane sans utiliser de scrollbar ).
    A bientôt ...

Discussions similaires

  1. affichage d'un fichier texte en php
    Par dgac2000 dans le forum Langage
    Réponses: 8
    Dernier message: 23/05/2007, 20h54
  2. Affichage d'un fichier texte dans une fenetre
    Par schwinny dans le forum Access
    Réponses: 3
    Dernier message: 11/08/2006, 09h53
  3. [Ada] Affichage d'un fichier texte
    Par sneb5757 dans le forum Ada
    Réponses: 9
    Dernier message: 12/06/2006, 11h14
  4. [C#]Lecture gros fichier texte
    Par kekesilo dans le forum Windows Forms
    Réponses: 5
    Dernier message: 20/05/2006, 14h58
  5. [VBA-E]Telecharger un gros fichier texte
    Par Elstak dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 10/04/2006, 10h16

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