Opérations sur les fichiers

Flux des données et des objets en Java

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

La lecture d'un fichier en PHP n'a rien de compliqué. Il suffit d'utiliser une méthode file_get_contents afin de récupérer son contenu. En Java le nombre de lignes est plus grand. Ceci ne veut pas forcément dire que les opérations sur les fichiers sont plus complexes à écrire.

Dans cette partie on abordera tout ce qui concerne le traitement de fichiers. Au début on analysera les façons de lire les fichiers locaux. Ensuite on passera au contenu des fichiers distincts. On terminera par un paragraphe consacré à l'écriture dans les fichiers.

Les opérations de lecture des fichiers s'effectuent sur la base d'un stream (flux). Il s'agit des portions de données qui sont échangées entre les applications. Ces portions ressemblées constituent le fichier complet. Elles peuvent être des bytes, objets, caractères ou types primitifs. On distingue 3 types des flux :

  1. Byte : l'échange est constituée de paquets des bytes. Chaque byte est composé de 8 bits.
  2. Caractères : l'échange est basée sur les caractères traduits dynamiquement selon les conventions Unicode.
  3. Buffered : il s'agit des flux traités dans la mémoire. Les deux types précédents sont de nature UNBUFFERED. Cela veut dire qu'ils sont gérés par le système d'exploitation. Ils nécessitent donc l'intervention d'un support extérieur (disque dur, réseau) ce qui peut ralentir les opérations de lecture et d'écriture. D'une manière générale, UNBUFFERED devrait être utilisé pour les fichiers d'une petite taille. Les types buffered sont lus par blocks tandis que les types unbuffered traitent des bytes. Voici un exemple de lecture buffered et non buffered.

    afficher le code

=================> faire les tests de comparaison entre buffered et unbuffered (http://java.sun.com/docs/books/performance/1st_edition/html/JPIOPerformance.fm.html)

On distingue également 2 flux qui pourraient faire partie du flux "caractères" : flux objet (object stream) et flux de données (data stream).

Le flux d'objets concerne les objets qui peuvent être sérialisés et sauvegardés dans un fichier. Il se base sur l'implémentation des classes ObjectInputStream et ObjectOutputStream. La classe exportée dans un fichier doit implémenter l'interface Serializable. Tous ses attributs doivent être du type serializable. Par défaut, tous les types primitifs sont serializables. Pour d'autres attributs, il faut se référer à la documentation de chaque classe pour y vérifier si elle est du type serializable. Voici l'exemple d'une opération sur le flux objets :

afficher le code

"In a class that implements Serializable, the programmer must ensure that every instance variable of the class is a Serializable type. Any instance variable that is not serializable must be declared transient to indicate that it is not Serializable and should be ignored during the serialization process. By default, all primitive-type variables are serializable. For variables of reference types, you must check the definition of the class (and possibly its superclasses) to ensure that the type is Serializable. By default, array objects are serializable. However, if the array contains references to other objects, those objects may or may not be serializable." http://www.deitel.com/articles/java_tutorials/20050923/IntroductionToObjectSerialization_Page3.html

Grâce à la gestion des données, on peut opérer sur les types primitifs plutôt que sur les bytes. Java possède des classes (DataInputStream et DataOutputStream) qui permettent de considérer le fichier directement en tant que la représentation d'un chiffre à virgule (float, double) ou d'un entier (int).

Il faut éviter d'utiliser les chiffres à virgule pour des opérations mathématiques car des valeurs n'ont pas de représentation binaire. Pour remedier à ce problème, il est conseillé d'utiliser les instances de BigDecimal. Elles peuvent être sauvegardées grâce au flux objets.

afficher le code

La sauvegarde (flush()) du buffeur est un élément qui permet d'écrire les données récupérées par la mémoire directement sur un support matériel (disque dur par exemple). Cette technique permet de sauvegarder les données du buffeur dans les points critiques. Elle peut empêcher une perte partielle des informations.

Certaines classes utilisent l'auto-sauvegarde (autoflush()). Par exemple, la classe PrintWriter sauvegarde les données automatiquement après chaque appel de la méthode println() ou format().

Si l'on utilise la méthode flush() dans la console, on peut être sûr que tout caractère ajouté sera affiché sur l'écran. Voici l'exemple avec la classe StringWriter :

afficher le code

Bartosz KONIECZNY Classes

Une question ? Une remarque ?

*

*

Un conseil Symfony2

Un problème filemtime()

Si pendant le développement de votre projet Symfony2 vous rencontrez un problème avec fonction filemtime, il peut s'agir d'un dysfonctionnement temporaire. Warning: filemtime() [function.filemtime]: stat failed for C:\Program Files (x86)\EasyPHP-5.3.5.0\www\gagu\src\Bun\DleBundle/Resources/views/Bundle/show.html.php in C:\Program Files (x86)\EasyPHP-5.3.5.0\www\appli\app\cache\dev\classes.php line 2064 Pour résoudre ce problème, vous pouvez être amenés à supprimer le cache du répertoire dev (si vous êtes en mode développement).