Introduction
Un comptoir doit mémoriser qui détient chaque outil après la fermeture de l’application. Cet environnement indépendant fournit des règles de prêt fonctionnelles et un nouveau fichier du comptoir, comprenant des prêts existants et un outil en maintenance. Son code de stockage incomplet perd actuellement l’état enregistré au chargement et n’écrit pas les modifications.
Vous convertirez des enregistrements UTF-8 en objets et n’enregistrerez que les modifications valides. Vous devez connaître les règles d’objets du lab précédent ; aucun fichier de cet environnement n’est nécessaire. Il s’agit d’une application pédagogique à un seul processus, pas d’une base de données ni d’une garantie contre les coupures de courant. Durée de lecture et de pratique estimée par l’auteur : 45 minutes.
Charger l’état réellement présent sur le disque
Dans cette étape, vous lirez un enregistrement de fichier ordinaire, puis corrigerez la façon dont l’état enregistré et les relations avec les emprunteurs deviennent des objets Java.
Ouvrez l’onglet Terminal. cd sélectionne le dossier de ce lab indépendant. Utilisez Ctrl+U pour effacer une ligne incorrecte du terminal qui n’a pas encore été exécutée. En cas d’erreur de chemin, revenez dans ce dossier et réessayez la bonne commande.
cd /home/labex/project/tool-library
L’application fournit des règles d’objets fonctionnelles, mais un stockage incomplet. Utilisez d’abord un petit fichier d’entraînement pour observer le format à cinq champs sans risquer les prêts existants. mkdir -p crée le dossier d’entraînement au besoin. printf écrit selon un format choisi : \t crée une tabulation et \n termine l’enregistrement ; > écrit sa sortie dans le fichier nommé en remplaçant une éventuelle copie d’entraînement antérieure. Les apostrophes empêchent le shell de modifier le format. cp copie la liste des membres à côté de ce fichier, car l’application cherche members.tsv à côté de son fichier de comptoir en entrée. Aucune de ces commandes ne modifie le vrai comptoir.
mkdir -p work
printf 'S01\tSpare drill\tAVAILABLE\t-\tPractice only\n' > work/sample.tsv
cp members.tsv work/members.tsv
Compilez le code source actuel. -encoding UTF-8 sélectionne son encodage de texte, -d out sélectionne la sortie compilée et *.java sélectionne les fichiers Java de ce dossier. Continuez uniquement si la compilation réussit sans erreur.
javac -encoding UTF-8 -d out *.java
-cp out indique à Java où trouver les classes. -Dfile.encoding=UTF-8 sélectionne l’encodage de texte à l’exécution. L’entrée d’entraînement est work/sample.tsv ; --memory empêche l’enregistrement de cette démonstration.
java -Dfile.encoding=UTF-8 -cp out Desk work/sample.tsv --memory
Dans le programme, saisissez ces lignes en appuyant sur Enter après chacune :
list
borrow S01 M01
list
quit
S01 commence dans l’état AVAILABLE, avec l’emprunteur - ; son prêt à M01 est accepté. Ce cas ordinaire fonctionne même avec le chargement incomplet, car la ligne d’entraînement possède déjà l’état supposé par le code défectueux. Il ne prouve pas la préservation des prêts existants. La modification d’entraînement disparaît à la fermeture de ce processus.
Lisez le vrai comptoir et les membres inscrits. cat affiche un fichier sans le modifier :
cat desk.tsv
cat members.tsv
Il y a cinq champs séparés par des tabulations : ID, nom, état de l’enum, emprunteur et note. Ce format contrôlé accepte les espaces et le texte UTF-8 dans les champs, mais pas les tabulations ni les sauts de ligne. T24 est déjà empruntée par M03 ; T25 est empruntée par M02 et porte la note Cafe workshop. T23 est en maintenance. Ces faits doivent être conservés au chargement. Ne modifiez pas directement desk.tsv, members.tsv ni le dossier reference.
Lisez le code de stockage fourni :
cat Store.java
Store constitue la frontière de persistance : les enregistrements deviennent des objets dans load ; les objets deviennent des enregistrements dans save. Files.readAllLines lit explicitement en UTF-8. fields(line) contrôle le format et fournit les champs f[0] à f[4]. Repérez l’appel new Tool(...) : il substitue actuellement Tool.State.AVAILABLE et "-" à chaque ligne. Prévoyez l’effet sur l’emprunteur de T24 et l’état de maintenance de T23. La boucle, la liste et les méthodes auxiliaires d’analyse et de validation sont déjà fournies ; conservez-les. Vous n’avez pas à réécrire leur implémentation avec HashSet.
Faites une sauvegarde des sources uniquement avant de modifier le code :
cp Store.java work/Store-before-load.java.txt
nano Store.java
Comme dans le premier lab, Ctrl+W recherche, Enter confirme la recherche, les flèches déplacent le curseur et Backspace corrige les caractères. Recherchez Tool tool = new Tool pour trouver cet unique appel de constructeur. Modifiez ses arguments d’état et d’emprunteur pour obtenir :
Tool tool = new Tool(f[0], f[1], Tool.State.valueOf(f[2]), f[3], f[4]);
Tool.State.valueOf(f[2]) transforme le nom d’enum enregistré en sa valeur d’enum ; f[3] restaure l’emprunteur enregistré. Conservez les arguments d’ID, de nom et de note, la boucle environnante et toutes les méthodes auxiliaires. Vous reconstituez des informations existantes, vous n’inventez pas un nouvel outil disponible. Enregistrez avec Ctrl+O, Enter, puis quittez avec Ctrl+X. Pour abandonner une erreur non enregistrée, utilisez Ctrl+X, N. Rouvrez le fichier et recherchez l’appel pour corriger une erreur de compilation. Si vous devez volontairement recommencer cette modification, cp work/Store-before-load.java.txt Store.java restaure uniquement ce fichier source ; refaites ensuite la conversion. Ne relancez jamais setup pour annuler des modifications.
Ici, throws IOException déclare que l’accès au fichier peut échouer. La boucle de commandes affiche Cannot continue et s’arrête en cas d’entrée manquante ou mal formée. C’est un problème de fichier, pas un prêt refusé. Corrigez le chemin indiqué ou la conversion dans le code source ; ne videz ni ne réécrivez les enregistrements originaux pour supprimer l’erreur.
Compilez le code source enregistré et lancez le vrai comptoir. Contrairement à la démonstration, omettez --memory : le vrai comptoir conservera les modifications valides une fois l’enregistrement terminé à l’étape suivante. Une erreur de syntaxe indique le fichier et la ligne ; corrigez-la dans nano et compilez avec succès avant de lancer, au lieu d’exécuter d’anciennes classes.
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv
Saisissez ces lignes dans le programme du comptoir :
list
members
quit
La liste doit conserver T24 → M03, T25 → M02, l’état MAINTENANCE de T23 et toutes les notes. members affiche les ID inscrits. Ouvrir et lister ne doivent pas réécrire le fichier. quit revient au shell. L’étape suivante complète le véritable enregistrement ; un simple message de réussite ne prouverait pas la persistance.
Enregistrer les modifications valides et rouvrir le comptoir
Dans cette étape, vous ferez survivre un nouveau prêt et un retour valide à la véritable fin du processus.
Partez du shell dans le même onglet Terminal. L’enregistrement sérialise chaque objet actuel, y compris les prêts et les fiches de maintenance non modifiés. row(tool) joint les cinq champs avec des tabulations. La boucle ajoute toutes les lignes à une liste ; Files.write les écrit en UTF-8. La boucle de commandes appelle save uniquement après le retour normal d’une méthode du domaine. Une action refusée ne doit pas écrire dans le fichier de données, même pour réécrire un contenu identique.
Lisez la structure de la boucle de commandes pour relier cette règle à la frontière de stockage :
cat Desk.java
Repérez found.borrow(c[2]), found.giveBack(c[2]) et l’appel suivant à Store.save(path, tools). Une exception levée par le domaine saute l’appel d’enregistrement et devient un refus normal. Conservez cet ordre fourni ; ajouter une écriture dans le gestionnaire de refus violerait le contrat.
Faites une sauvegarde des sources uniquement qui conserve votre chargement corrigé :
cp Store.java work/Store-before-save.java.txt
nano Store.java
Appuyez sur Ctrl+W, recherchez TODO: write all rows, puis appuyez sur Enter. Lisez la boucle juste au-dessus : elle recueille une ligne sérialisée pour chaque outil, y compris les prêts non modifiés. Utilisez les flèches pour aller à la fin de ce commentaire, puis Backspace pour supprimer ses caractères. Saisissez l’écriture avec la même indentation. Remplacez uniquement le commentaire TODO par cette écriture réelle après la boucle et avant l’accolade fermante de la méthode :
Files.write(path, rows, StandardCharsets.UTF_8);
path est le fichier de comptoir choisi ; rows est la liste sérialisée complète, pas uniquement le dernier objet modifié. L’encodage explicite préserve celui du texte de chaque champ. Conservez la méthode load corrigée, la boucle des lignes et toutes les méthodes auxiliaires. Enregistrez avec Ctrl+O, Enter, Ctrl+X. En cas d’erreur non enregistrée, Ctrl+X, N l’abandonne. Pour une erreur de code source enregistrée, rouvrez et corrigez le fichier ; cp work/Store-before-save.java.txt Store.java permet un retour arrière facultatif limité au code source, qui conserve votre chargement. Refaites ensuite l’écriture. Ne réinitialisez pas le fichier du comptoir et ne relancez pas setup.
Recompilez le code source enregistré :
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv
Saisissez ce qui suit dans le comptoir :
borrow T21 M01
borrow T21 M02
return T24 M01
borrow T23 M01
borrow TYPO M01
return T24 M03
list
quit
T21 est empruntée par M01. Le second prêt, le mauvais auteur du retour, le prêt de l’outil en maintenance et l’ID mal saisi sont volontairement refusés. Seul le retour de T24 par M03 réussit. T22 reste disponible, T23 reste en maintenance et T25 reste empruntée par M02 avec sa note d’origine. Le refus de l’ID inconnu laisse la boucle utilisable ; corrigez l’ID au lieu de redémarrer ou de réinitialiser.
Lancez maintenant un nouveau processus Java avec le même fichier :
java -Dfile.encoding=UTF-8 -cp out Desk desk.tsv
list
quit
T21 doit toujours être BORROWED par M01, et T24 doit toujours être AVAILABLE, avec l’emprunteur -. Sinon, vérifiez que vous avez compilé le Store.java actuel et lancé sans --memory. Ne modifiez pas les enregistrements finaux pour imiter un prêt enregistré. Si une opération acceptée a déjà été sauvegardée, ne la répétez pas uniquement parce qu’elle est maintenant refusée ; list affiche la réalité actuelle.
De retour au shell, lisez le résultat réellement enregistré :
cat desk.tsv
Les relations des enregistrements doivent correspondre à la liste du nouveau processus. Conservez tous les ID, noms, membres, états de maintenance, prêts non concernés et notes. Seuls l’état/l’emprunteur de T21 et l’état/l’emprunteur de T24 changent. Ce petit composant d’écriture remplace le fichier lors d’un enregistrement réussi ; il ne fournit ni accès concurrent, ni récupération après plantage, ni transaction atomique. Si l’écriture échoue, arrêtez-vous et examinez l’erreur avant de continuer.
Résumé
Vous avez transformé des enregistrements UTF-8 en objets Java, enregistré chaque enregistrement actuel après une transition valide et rouvert le comptoir dans un nouveau processus. Les prêts existants, la maintenance et les notes sont restés intacts, tandis que les opérations refusées n’ont rien écrit dans le stockage.



