[Java] Objets serializables : comptage, sélection

Démarré par Valoo, 07 Septembre 2012 à 21:55

0 Membres et 2 Invités sur ce sujet

07 Septembre 2012 à 21:55 Dernière édition: 12 Septembre 2012 à 20:15 par Valoo
Bonjour,

Je suis en train de réaliser une petite application, toute simple, pour tester son vocabulaire dans une langue étrangère.

Le principe est simple : l'utilisateur peut rentrer via l'interface des mots : il précise les traductions française et allemande puis un objet Mot est créé et ajouté dans un fichier "dictionnaire.txt".

Pour être interrogé, l'utilisateur demande alors à l'application qu'une question lui soit posée : un mot (en allemand ou en français) est tiré au hasard dans le dictionnaire et il doit en taper la traduction.

Bien évidemment, l'utilisateur peut à tout moment choisir d'être interrogé, ou bien d'entrer de nouveaux mots dans le dictionnaire. Voilà pour le contexte général.

Je me suis donc servi des objets "serializables", découverts récemment dans un tuto sur le site du zéro, afin de pouvoir conserver tous mes objets "Mots" dans un fichier, même quand l'utilisateur quitte et décide de rejouer le lendemain.

Je pense que je suis quasiment au bout du programme (en même temps j'admets qu'il n'est pas bien compliqué). Je ne suis pas un programmeur émérite et il me reste quelques problèmes centraux que je n'arrive pas à résoudre. J'ai tâché de trouver par moi-même un bon moment, mais je ne m'en sors pas, c'est pourquoi je me tourne vers vous.

Premier problème : Je n'arrive pas à savoir comment faire pour pouvoir, à tout moment, compter le nombre d'objets enregistrés dans le dictionnaire. Cela est crucial afin de connaître la borne supérieure de l'intervalle dans lequel il faut tirer un entier au hasard pour poser une question. Je souhaiterais en quelque sorte incrémenter un compteur tant que l'exception EOF n'est pas levée, mais je ne sais pas comment faire.

Pour le moment, j'ai forcé le nombre de mots dans le dictionnaire à 5. C'est très superficiel, mais uniquement pour tester ce qui va m'amener au deuxième problème. Ce que j'ai essayé jusqu'à lors est commenté.

Deuxième problème : Je ne parviens pas à aller chercher le n-ième mot dans le dictionnaire. Dès que je tire au sort un mot, le programme m'interroge irrémédiablement sur le premier mot du dictionnaire. En somme, je n'arrive pas à le parcourir.

Quand je teste le programme, j'obtiens également ces messages dans l'output : "java.io.StreamCorruptedException : invalid type code : AC". Je ne sais pas à quoi ça correspond, mais cela ne fait pas planter le programme.

Je vous donne les sources : [lien retiré]

Il y a pas mal de code mis en commentaire. Il s'agit soit de code mort, soit de choses essayées, qui n'ont pas fonctionné, mais que je souhaitais garder sous les yeux. Si jamais quelque chose n'est pas clair ou bien si il manque des informations utiles, demandez moi des précisions  ^_^

D'avance, merci beaucoup  :)
Suivez mon défi fou : finir de nouveau chaque Zelda, à 100%, dans leur ordre chronologique afin de permettre une réécriture au fur et à mesure de la légende.

Bon, ça n'est pas une réponse vraiment construite, pas plus qu'une solution, mais une idée de design : pour ton dictionnaire, plutôt que de relire le fichier et de rechercher la ligne voulue à chaque fois, tu pourrais peut-être ne le lire qu'une seule fois à la création du dictionnaire (ou un peu plus tard si tu veux) et tout stocker dans une TreeMap : ça te permettrait de récupérer simplement sa taille et d'accéder aux éléments directement par index comme tu le veux en faisant juste appel aux fonctions de la TreeMap. En plus, ça éviterait toutes les opérations de lecture du fichier qui sont en général assez lourdes :)

+1 ce que dis Morwenn, tu veux accéder au fichier seulement une fois pour le charger en mémoire dans une structure de données. Ensuite les structures java te donnent des méthodes style count (ou size je sais plus) qui résoudront tes problèmes.

Ensuite quand l'utilisateur ajoute des mots, tu mets à jour ta structure et t'écris sur le disque

Hum je vois, je n'avais pas pensé à cela, et c'est vrai que ça résoudrait pas mal de choses.

L'utilisateur pourrait rentrer ses mots, et à tout moment choisir quelque chose du genre "mettre à jour le dictionnaire", pour être interrogé également sur ce qu'il vient d'entrer.

Le seul truc qui me chiffonne encore : comment parcourir le fichier pour rentrer les mots dans la structure de données temporaire ? Car je risque de retomber sur ce que j'ai appelé le "deuxième problème".
Suivez mon défi fou : finir de nouveau chaque Zelda, à 100%, dans leur ordre chronologique afin de permettre une réécriture au fur et à mesure de la légende.

Citationcomment parcourir le fichier pour rentrer les mots dans la structure de données temporaire ?

Si tu utilises une structure de données sérialisable, tu n'as pas à te soucier de cela. Java fait tout pour toi, tu as juste à appeller la méthode qu'il faut (longtemps que je n'ai pas fait de Java, je ne me souviens plus, mais ça doit être facile à trouver dans la doc)

C'est tout l'intérêt des objets sérialisables: on n'a pas à se soucier de parcourir le fichier. D'ailleurs, tu trouveras que mis à part en C, tu as rarement à parcourir un fichier à proprement parler (à moins que tu n'écrives une librairie bas niveau).

De mémoire de ce que j'avais fait pour un projet, il suffit d'implémenter l'interface Serializable pour ta classe.
( google me donne ça http://docs.oracle.com/javase/1.4.2/docs/api/java/io/Serializable.html)

Les structures de données du Collection framework de java sont généralement Serializable.
Tu peux trouver celle qui te convient le mieux ici pour java 1.6 et ici pour java 1.7, il y a quelques trucs en plus je ne sais plus quoi, il suffit de lire.
Le plus simple c'est de rendre ton objet Serializable (ce qui semble déjà être le cas) le mettre dans la structure de donnée et comme dit Guillaume sauvegarder la structure de donnée directement dans un fichier a coup d'ObjectOutputStream.

C'est la méthode la plus simple, sauf que la sérialisation en java c'est juste une horreur en espace occupé, ne t'étonne pas trop de la taille du fichier.
Citation
Ash Nazg Durbatulùk, Ash Nazg Gimbatul,
Ash Nazg Thrakatulùk agh bruzum-ishi krimpatul.
The fellowship of the Ring - J.R.R. Tolkien

08 Septembre 2012 à 22:24 #7 Dernière édition: 12 Septembre 2012 à 20:16 par Valoo
Merci pour vos réponses, elles m'ont bien aidé. J'ai fait, je pense, toutes les corrections nécessaires. Cela devrait bientôt fonctionner. :)

Bientôt, car il m'est apparu un nouveau problème, que je n'avais pas auparavant : le fichier "dictionnaire.txt" ne se crée plus. Je ne sais pas s'il s'agit d'une inattention de ma part, ou d'une véritable erreur. Toujours est-il que je ne comprends pas pourquoi cela se produit.

Les sources en ligne sont à jour. Je vous remets le lien : [lien retiré]

Selon moi, il ne reste plus qu'à régler ce problème de fichier qui n'apparaît plus. Et à écraser l'ancien fichier avec un autre contenant le nouveau dictionnaire lorsque l'on quitte le programme.
Suivez mon défi fou : finir de nouveau chaque Zelda, à 100%, dans leur ordre chronologique afin de permettre une réécriture au fur et à mesure de la légende.

12 Septembre 2012 à 02:54 #8 Dernière édition: 12 Septembre 2012 à 20:16 par Valoo
Problèmes résolus. Le tout fonctionne désormais très bien sous Netbeans.

Plus qu'à trouver comment faire correctement le jar pour le distribuer ensuite, et c'est réglé !


Merci à tous ceux qui m'ont répondu  ^_^

edit : C'est bouclé.
Au cas où le résultat final intéresserait quelqu'un : http://valoo0278.free.fr/VocFrAll.zip
Suivez mon défi fou : finir de nouveau chaque Zelda, à 100%, dans leur ordre chronologique afin de permettre une réécriture au fur et à mesure de la légende.