:: Enseignements :: Master :: M1 :: 2017-2018 :: Programmation d'applications réseaux ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Manipulation de base des buffers, jeux de caractères et endianness |
Pour cette séance, nous vous fournissons
File2Hex.jar qui permet
d'afficher en hexadécimal les octets contenus dans un fichier passé en argument.
% java -jar File2Hex filename
Exercice 1 - Endianness
On souhaite écrire une classe
StoreWithByteOrder qui lit des entiers long sur l'entrée standard
et qui les écrit octet par octet dans un fichier. L'ordre (little endian
ou big endian) d'écriture des octets dans le fichier doit être celui
spécifié sur la ligne de commande par LE ou BE juste avant le nom du fichier.
Par exemple, les commandes
% java fr.upem.buffers.StoreWithByteOrder BE long-be.txt
1
^D
et
% java fr.upem.buffers.StoreWithByteOrder LE long-le.txt
1
^D
doivent produire deux fichiers différents. Pour savoir ce que contiennent ces
fichiers, vous pouvez utiliser le jar
File2Hex donné en début d'exercice.
Exercice 2 - Lecture d'un fichier comme un fichier texte avec encodage
On souhaite écrire une classe LoadWithEncoding qui
accepte deux arguments sur la ligne de commande:
le nom d'un jeu de caractères, et le nom d'un fichier. La fonction main doit alors
afficher la chaîne correspondant aux octets du fichier
dont le nom est fourni en second argument en utilisant l'encodage préconnisé en premier argument.
Si un seul argument est donné alors la classe lira les octets sur l'entrée standard (jusqu'à trouver
une fin de flot qui peut être donnée en tapant Control-D).
On va utiliser la méthode charset.decode() pour passer des octets à la chaîne de caractères correspondante.
Expliquez pourquoi il est nécessaire d'avoir tous les octets du fichier avant d'appeler la méthode decode.
En partant du squelette
LoadWithEncoding.java, complétez la méthode
fileToString qui correspond au cas où deux paramètres
sont donnés et où la lecture se fait dans un fichier. Vous pourrez obtenir la taille en octets du fichier en appelant la méthode
fileChannel.size().
Attention: même si le buffer fait la même taille que le fichier, la méthode
fileChannel.read() n'est pas garantie de remplir le buffer en un seul appel.
Il faut donc l'appeler jusqu'à ce que le buffer soit plein (
!buffer.hasRemaining()).
Vous pouvez tester votre programme avec le fichier
test.txt
% java fr.upem.buffers.LoadWithEncoding utf8 test.txt
qui doit afficher:
a€
Alors que,
% java fr.upem.buffers.LoadWithEncoding iso-8859-1 test.txt
devrait afficher:
aâ ¬
Utilisez
File2Hex pour comprendre cet affichage.
Complétez la méthode
stringFromStandardInput qui correspond à la lecture sur l'entrée standard.
On peut obtenir une
ReadableByteChannel correspondant à l'entrée standard avec:
ReadableByteChannel in = Channels.newChannel(System.in);
Question 1.Une
ReadableByteChannel se comporte comme un
FileChannel en lecture sauf que l'on ne peut pas connaitre à l'avance la taille en octets.
Il faudra donc lire dans un buffer de taille fixe et agrandir ce buffer quand il est plein. Pour agrandir, on créera un buffer deux fois plus grand
et on copiera l'ancien buffer dans ce nouveau buffer. Pour copier la zone de travail d'un
ByteBuffer src au début de la zone de travail
d'un
ByteBuffer dst, on utilise
dst.put(src).
© Université de Marne-la-Vallée