{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f8486225-da5a-4eab-b8af-e2e792f75ec1",
   "metadata": {
    "tags": []
   },
   "source": [
    "---\n",
    "title: Sérialisation en Java\n",
    "description: Introduction à la sérialisation d'object.\n",
    "categories: \n",
    "  - Java\n",
    "  - I111\n",
    "  - PO43\n",
    "  - Lecture\n",
    "provide_notes: true\n",
    "provide_slides: true\n",
    "jupyter: java\n",
    "---  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c967e43e-fa33-4a68-962e-a0f54c127e03",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "f085753b-7501-436d-b487-c6a0f51d38f1",
   "metadata": {},
   "source": [
    "## Définition de la Sérialisation\n",
    "\n",
    "- **Qu'est-ce que la sérialisation ?**\n",
    "  - Transformation de l'état d'un objet (valeurs des variables d'instance) en une suite d'octets.\n",
    "  \n",
    "- **Pourquoi sérialiser ?**\n",
    "  - **Conservation de l'état** : Sauvegarder l'état d'un objet pour une utilisation future.\n",
    "  - **Reconstruction** : Restaurer un objet avec le même état à partir des octets sérialisés.\n",
    "\n",
    "- **Outils en Java** :\n",
    "  - `ObjectOutputStream` : Pour écrire l'état de l'objet en octets.\n",
    "  - `ObjectInputStream` : Pour lire les octets et reconstruire l'objet."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "346f4c5f-986d-4d08-80d3-50d6dae70042",
   "metadata": {},
   "source": [
    "## Qu’est-ce qui est sérialisé ?\n",
    "\n",
    "- **Variables d'instance** : Valeurs des variables d'instance (pas des variables de classe).\n",
    "- **Informations sur les classes** :\n",
    "  - Nom de la classe\n",
    "  - Noms, types et modificateurs des variables à sauvegarder\n",
    "- **Compatibilité** : Informations pour détecter les modifications de classe entre sérialisation et désérialisation."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44d8f4c6-5e36-45f7-8566-b5fa1398e799",
   "metadata": {},
   "source": [
    "## Utilisation de la Sérialisation\n",
    "\n",
    "- **Sauvegarde** : Conserver un objet dans un fichier ou une base de données pour une récupération ultérieure.\n",
    "- **Configuration** : Sauvegarder la configuration d’un composant (ex. JavaBean) pour une réutilisation future.\n",
    "- **Communication distante (RMI)** :\n",
    "  - Sérialiser les paramètres non primitifs d’une méthode.\n",
    "  - Transmettre les octets sur le réseau.\n",
    "  - Reconstruire le paramètre sur la machine distante."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81e607e7-7cd2-47d1-82a1-01a5b50e47fd",
   "metadata": {},
   "source": [
    "## Interface Serializable\n",
    "\n",
    "- **Condition de sérialisation** : Un objet doit être une instance d’une classe implémentant `Serializable`.\n",
    "- **Interface marquante** : Ne contient aucune méthode, sert à marquer les classes sérialisables.\n",
    "- **Classes sérialisables** : La plupart des classes du JDK le sont.\n",
    "- **Exceptions** :\n",
    "  - Certaines classes ne peuvent pas être sérialisées (ex. `InputStream`).\n",
    "  - D'autres ne doivent pas l'être pour des raisons de sécurité.\n",
    "- **Variables transientes** :\n",
    "  - Utiliser `transient` pour exclure une variable d'instance de la sérialisation : `private transient int val;`.\n",
    "  - À la désérialisation, la variable reçoit sa valeur par défaut ou doit être recalculée si nécessaire."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c80cdc8-ab21-4c4f-9273-cc1b1245adce",
   "metadata": {},
   "source": [
    "## Compression/Décompression\n",
    "\n",
    "- **Paquetage `java.util.zip`** : Classes filtres pour compresser des flots.\n",
    "  - **GZIP** : `GZIPInputStream` et `GZIPOutputStream` pour le format GZIP.\n",
    "  - **ZIP** : `ZipInputStream` et `ZipOutputStream` pour le format ZIP.\n",
    "- **Lecture performante des fichiers ZIP** : Utiliser `java.util.zip.ZipFile`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ea52c0c4-75ae-41c5-b95f-43638ecb51f1",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7d94effb-59bb-4ec0-be10-4e603e923b96",
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.zip.GZIPOutputStream;\n",
    "import java.util.zip.GZIPInputStream;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e7280122-566c-4f7b-a106-bb7a60ef5ee2",
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "//| echo: true\n",
    "\n",
    "// Définition d'un enregistrement immuable Dog qui implémente Serializable\n",
    "record Dog(int id, String name) implements Serializable {};\n",
    "\n",
    "String filename=\"/tmp/mesChiens.bin.gz\";\n",
    "\n",
    "// Utilisation d'un bloc try-with-resources pour assurer la fermeture des flux\n",
    "try (ObjectOutputStream oos = new ObjectOutputStream(\n",
    "    new GZIPOutputStream (\n",
    "        new FileOutputStream (filename)));) {\n",
    "    \n",
    "// Sérialisation et compression des objets Dog\n",
    "oos.writeObject(new Dog(1,\"Medor\"));\n",
    "oos.writeObject(new Dog(2,\"Rex\")); }"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df83402d-4831-4ff5-8244-561d26202f6d",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "9671551d-b427-46f8-b925-629a1cc50ab7",
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dog[id=1, name=Medor]\n",
      "Dog[id=2, name=Rex]\n"
     ]
    }
   ],
   "source": [
    "//| echo: true\n",
    "//| output: true\n",
    "\n",
    "        try (ObjectInputStream ois = new ObjectInputStream(\n",
    "                new GZIPInputStream(\n",
    "                    new FileInputStream(filename)))) {\n",
    "\n",
    "            // Boucle infinie pour lire tous les objets Dog du fichier\n",
    "            while (true) {\n",
    "                // Lecture et affichage de chaque objet Dog\n",
    "                System.out.println((Dog) ois.readObject());\n",
    "            }\n",
    "        } catch (EOFException e) {\n",
    "            // Fin de fichier atteinte, sortie de la boucle\n",
    "        } catch (Exception e) {\n",
    "            // Gestion des autres exceptions potentielles\n",
    "            e.printStackTrace();\n",
    "        }\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f184263-5a94-468d-93d5-2a81d06960cd",
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "java [env:base] *",
   "language": "java",
   "name": "conda-base-java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "21.0.4+7-LTS"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
