Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Lecture et écriture de fichier binaire

2 réponses
Avatar
Jean-Claude Arbaut
Bonjour,

J'aimerais lire et écrire des tableaux (essentiellement des "double",
mais éventuellement d'autres types au milieux, comme des entiers pour
les dimensions ou des chaînes pour les noms de colonnes/lignes).
J'ai fait quelques essais avec RandomAccessFile, et j'ai été horrifié
par la lenteur du bidule: les E/S n'ont pas l'air d'utiliser un buffer,
ou alors je ne saisis pas. J'ai essayé aussi un
DataOutputStream(new BufferedOutputStream(new FileOutputStream(...))),
et la vitesse est nettement plus raisonnable: en gros, pour écrire 80M,
il me fallait 3.5 minutes avec la première version, et 1.7s avec la
deuxième. Maintenant, j'ai deux autres problèmes:
* je ne peux plus utiliser "seek", puisque ce sont des flux. Or pour
lire des fichiers de données structurées (une image TIFF par exemple),
ce serait pratiquement indispensable.
* Je ne peux lire ou écrire qu'en BigEndian. Il y a pas mal de types
de fichiers en LittleEndian :-)

Pour la première question, j'envisage de passer par le RandomAccessFile
mais en utilisant des byte[], ce qui m'obligerait à convertir mes
données de double[] en byte[] (je crois qu'il y a des classes qui font
ça). En espérant qu'écrire par gros blocs irait plus vite que mon
précédent programme.

Est-ce que vous savez s'il y a une meilleure approche pour pouvoir
faire des E/S binaires structurées (types de données mélangés,
utilisation de seek) ? C'est quand même énervant de ne pas pouvoir
faire un fseek(), fread() :D

Pour le LittleEndian, j'ai trouvé des classes qui contournent
le problème, donc au pire je pourrais les utiliser, mais
je me demande s'il n'y a pas déjà une solution dans les API.

2 réponses

Avatar
TestMan
Jean-Claude Arbaut wrote:
Bonjour,

J'aimerais lire et écrire des tableaux (essentiellement des "double",
mais éventuellement d'autres types au milieux, comme des entiers pour
les dimensions ou des chaînes pour les noms de colonnes/lignes).
J'ai fait quelques essais avec RandomAccessFile, et j'ai été horrifié
par la lenteur du bidule: les E/S n'ont pas l'air d'utiliser un buffer,
ou alors je ne saisis pas. J'ai essayé aussi un
DataOutputStream(new BufferedOutputStream(new FileOutputStream(...))),
et la vitesse est nettement plus raisonnable: en gros, pour écrire 80M,
il me fallait 3.5 minutes avec la première version, et 1.7s avec la
deuxième. Maintenant, j'ai deux autres problèmes:
* je ne peux plus utiliser "seek", puisque ce sont des flux. Or pour
lire des fichiers de données structurées (une image TIFF par exemple),
ce serait pratiquement indispensable.
* Je ne peux lire ou écrire qu'en BigEndian. Il y a pas mal de types
de fichiers en LittleEndian :-)



Bonjour,

Un flux n'est pas forcement seekable et les I/O Java ne sont pas
bufferisées par défaut, il est de votre responsabilité d'en assurer le
controle ;-) Si vous cherchez plus de perf, vous pouvez aussi vous
plonger dans les NIO.

Heureusement pour le images il y a :
http://java.sun.com/javase/6/docs/api/javax/imageio/stream/package-summary.html

Pour la première question, j'envisage de passer par le RandomAccessFile
mais en utilisant des byte[], ce qui m'obligerait à convertir mes
données de double[] en byte[] (je crois qu'il y a des classes qui font
ça). En espérant qu'écrire par gros blocs irait plus vite que mon
précédent programme.

Est-ce que vous savez s'il y a une meilleure approche pour pouvoir
faire des E/S binaires structurées (types de données mélangés,
utilisation de seek) ? C'est quand même énervant de ne pas pouvoir
faire un fseek(), fread() :D



ImageIO, NIO pour garder le controle sur le format
Serialization sinon ;-)

Pour le LittleEndian, j'ai trouvé des classes qui contournent
le problème, donc au pire je pourrais les utiliser, mais
je me demande s'il n'y a pas déjà une solution dans les API.



ImageIO, NIO ...

A+
TM
Avatar
Emmanuel Bourg
As tu essayé avec un FileChannel ?

Jean-Claude Arbaut a écrit :
Bonjour,

J'aimerais lire et écrire des tableaux (essentiellement des "double",
mais éventuellement d'autres types au milieux, comme des entiers pour
les dimensions ou des chaînes pour les noms de colonnes/lignes).
J'ai fait quelques essais avec RandomAccessFile, et j'ai été horrifié
par la lenteur du bidule: les E/S n'ont pas l'air d'utiliser un buffer,
ou alors je ne saisis pas. J'ai essayé aussi un
DataOutputStream(new BufferedOutputStream(new FileOutputStream(...))),
et la vitesse est nettement plus raisonnable: en gros, pour écrire 80M,
il me fallait 3.5 minutes avec la première version, et 1.7s avec la
deuxième. Maintenant, j'ai deux autres problèmes:
* je ne peux plus utiliser "seek", puisque ce sont des flux. Or pour
lire des fichiers de données structurées (une image TIFF par exemple),
ce serait pratiquement indispensable.
* Je ne peux lire ou écrire qu'en BigEndian. Il y a pas mal de types
de fichiers en LittleEndian :-)

Pour la première question, j'envisage de passer par le RandomAccessFile
mais en utilisant des byte[], ce qui m'obligerait à convertir mes
données de double[] en byte[] (je crois qu'il y a des classes qui font
ça). En espérant qu'écrire par gros blocs irait plus vite que mon
précédent programme.

Est-ce que vous savez s'il y a une meilleure approche pour pouvoir
faire des E/S binaires structurées (types de données mélangés,
utilisation de seek) ? C'est quand même énervant de ne pas pouvoir
faire un fseek(), fread() :D

Pour le LittleEndian, j'ai trouvé des classes qui contournent
le problème, donc au pire je pourrais les utiliser, mais
je me demande s'il n'y a pas déjà une solution dans les API.