TP3 JAVA 2 : Les flux
Les flux séquentiels : Ces flux peuvent être associés à des fichiers, des tableaux, ou des connexions
réseau. Deux styles de flux séquentiels :
les flux d’octets en lecture et en écriture :
(InputStream, OutputStream)
les flux de caractères en lecture et en écriture nécessite un encodage (Charset UTF-8) :
(Reader, Writer)
1. File
La classe File encapsule les fonctionnalités de gestion de fichier : Suppression, renommage, date
de la dernière modification, etc …
a. Constructeurs
File (String chemin) : Crée un nouveau File associé au nom chemin.
b. Méthodes :
boolean canRead() Renvoie vrai si le fichier peut être lu, et faux sinon.
boolean canWrite() Renvoie vrai si le fichier peut être écrit, et faux sinon.
int compareTo(File pathname) Comparaison des 2 chemins
boolean createNewFile() Création d’un nouveau fichier vide, et renvoie vrai si le
nouveau fichier n’existait pas avant sa création.
boolean delete() Supprime le fichier
void deleteOnExit() Supprime le fichier à la fin de l’exécution de la machine
virtuelle.
boolean exists() Renvoie vrai si et seulement si le fichier existe.
String getAbsolutePath() Retourne le chemin absolu
String getCanonicalPath() Retourne le chemin absolu
String getName() Retourne le nom du fichier.
String getPath() Retourne le chemin du fichier.
boolean isDirectory() Retourne vrai s’il s’agit d’un répertoire et faux sinon.
boolean isFile() Retourne vrai s’il s’agit d’un fichier "normal" et faux
sinon.
long lastModified() Retourne la date de la dernière modification sous forma
de long. Date d = new Date(f .lastModified()) ;
long length() La longueur du fichier, en octets.
String[] list() Retourne la liste des fichiers contenus dans le répertoire
spécifié par le File. Si le File n'est pas un répertoire le
tableau retourné vaut null.
File[] listFiles() Retourne la liste des fichiers contenus dans le répertoire
spécifié par le File. Si le File n'est pas un répertoire le
tableau retourné vaut null.
boolean mkdir() Crée un répertoire.
boolean mkdirs() Crée un répertoire, et tous ses parents nécessaires.
L'appel de mkdir avec un File constitué de "\\" retourne
false.
boolean renameTo(File dest) Renomme un fichier. retourne false si le file dest existe
déjà, et le renommage n'est pas effectué.
boolean setReadOnly() Marque le fichier en lecture seule
Q1. Décrire brièvement les méthodes de la classe File utilisé ainsi que le résultat de ce code ?
import java.io.File;
public class File {
public static void main(String[] args) {
File f = new File("test.txt");
System.out.println("Chemin absolu du fichier : " + f.getAbsolutePath());
System.out.println("Nom du fichier : " + f.getName());
System.out.println("Est-ce qu'il existe ? " + f.exists());
System.out.println("Est-ce un répertoire ? " + f.isDirectory());
System.out.println("Est-ce un fichier ? " + f.isFile());
System.out.println("Affichage des lecteurs à la racine du PC : ");
for(File file : f.listRoots())
{ System.out.println(file.getAbsolutePath());
try {
int i = 1;
//On parcourt la liste des fichiers et répertoires
for(File nom : file.listFiles()){
//S'il s'agit d'un dossier, on ajoute un "/"
System.out.print("\t\t" + ((nom.isDirectory()) ? nom.getName()+"/" : nom.getName()));
if((i%4) == 0){
System.out.print("\n"); }
i++; }
System.out.println("\n");
} catch (NullPointerException e) {
//L'instruction peut générer une NullPointerException
//s'il n'y a pas de sous-fichier !
} } }}
2. InputStreamReader
La classe InputStreamReader établit un pont entre les flux d'octets et les flux de caractères. Cette
classe permet de lire des octets et les traduit en caractères en utilisant un décodage spécifique.
L'appel de la méthode read() d'un InputStreamReader va effectuer la lecture de 1 ou plusieurs
octets.
a. Le constructeur :
InputStreamReader( InputStream in) Crée un InputStreamReader qui utilise le charset
par défaut.
3. FileInputStream et FileOutputStream
C'est par le biais des objets FileInputStream et FileOutputStream que nous allons pouvoir :
Lire un fichier
Écrire dans un fichier
Q2. Exécuter le code suivant et expliquer son rôle ?
Q3. Quel est le type de l’information utilisé avec la classe FileInputStream et FileOutputStream ?
Q4. Donner la condition pour que l’objet FileInputStream fonctionne ? Que se passe-t-il si cette
condition n’est pas respectée ?
import java.io.*;
public class FileStream {
public static void main(String[] args) {
// Nous déclarons nos objets en dehors du bloc try/catch
FileInputStream fis = null;
FileOutputStream fos = null;
try {
// On instancie nos objets : // fis va lire le fichier // fos va écrire dans le nouveau !
fis = new FileInputStream(new File("TP3.txt"));
fos = new FileOutputStream(new File("test2.txt"));
// On crée un tableau de byte pour indiquer le nombre de bytes lus à chaque tour de
boucle
//byte[] buf = new byte[8];
// On crée une variable de type int pour y affecter le résultat de // la lecture Vaut -1
quand c'est fini
int n = 0;
// Tant que l'affectation dans la variable est possible, on boucle // Lorsque la lecture du
fichier est terminée l'affectation n'est // plus possible ! // On sort donc de la boucle
while ((n = fis.read()) >= 0) {
// On écrit dans notre deuxième fichier avec l'objet adéquat
fos.write(n);
// On affiche ce qu'a lu notre boucle au format byte et au // format char
System.out.print("\t" + n + "(" + (char) n + ")");
System.out.println(""); }
//Nous réinitialisons le buffer à vide
//au cas où les derniers bytes lus ne soient pas un multiple de
System.out.println("Copie terminée !");
fis.close(); fos.close();
} catch (FileNotFoundException e) {
System.out.println("le fichier introuvable");
} catch (IOException e) {
}}}
4. Les objets FilterInputStream et FilterOutputStream
Ces deux classes sont en fait des classes abstraites. Elles définissent un comportement global pour
leurs classes filles qui, elles, permettent d'ajouter des fonctionnalités aux flux d'entrée/sortie ! La
figure suivante schématisant leur hiérarchie.
DataInputStream : offre la possibilité de lire directement des types primitifs (double, char,int)
grâce à des méthodes comme readDouble(), readInt()…
BufferedInputStream ou BufferedReader: cette classe permet d'avoir un tampon à disposition
dans la lecture du flux. En gros, les données vont tout d'abord remplir le tampon, et dès que
celui-ci est plein, le programme accède aux données.
Exemple :
FileInputStream fis = new FileInputStream(new File("java2.txt"));
DataInputStream dis = new DataInputStream(fis);
BufferedInputStream bis = new BufferedInputStream(dis);
//Ou en condensé :
BufferedInputStream bis = new BufferredInputStream( new DataInputStream ( new
FileInputStream( new File("java2.txt"))));
5. DataInputStream et DataOutputStream
import java.io.*;
public class TestData {
public static void main(String[] args) {
//Nous déclarons nos objets en dehors du bloc try/catch
DataInputStream dis;
DataOutputStream dos;
try {
dos = new DataOutputStream( new FileOutputStream ("fff.txt"));
//Nous allons écrire chaque type primitif
dos.writeBoolean(true);
dos.writeByte(100);
dos.writeChar('C');
dos.writeDouble(12.05);
dos.writeFloat(100.52f);
dos.writeInt(1024);
dos.writeLong(123456789654321L);
dos.writeShort(2);
dos.close();
//On récupère maintenant les données !
dis = new DataInputStream(
new FileInputStream("fff.txt"));
System.out.println(dis.readBoolean());
System.out.println(dis.readByte());
System.out.println(dis.readChar());
System.out.println(dis.readDouble());
System.out.println(dis.readFloat());
System.out.println(dis.readInt());
System.out.println(dis.readLong());
System.out.println(dis.readShort());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace(); }}}
Q5. Expliquer le résultat de ce code et préciser quels sont les types primitifs utilisés ainsi que leurs
méthodes ?
Q6. Est-ce que on peut ajouter une chaine de caractère au fichier de sortie ? Pourquoi ? Si non que
suggérer vous ?
6. Ecrire et lecture des lignes de String dans des fichiers
Q7. Créer un fichier "read.txt" et écrire plusieurs lignes dans ce fichier ?
Q8. Implémenter ce code et décrire son fonctionnement ?
Q9. Préciser le rôle de la classe BufferedReader
import java . io .*;
class read {
public static void main ( String args []) throws IOException {
String thisLine ;
FileInputStream fis = new FileInputStream ( "read.txt" );
BufferedReader myInput = new BufferedReader( new InputStreamReader(fis) );
while (( thisLine = myInput.readLine()) != null ) {
System . out . println ( thisLine );
}
}}
Q10. Développer ce code suivant et décrire son fonctionnement ? Préciser le rôle de la classe
PrintWriter
import java . io .*;
class write {
public static void main ( String args []) throws IOException {
BufferedReader exemple = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Entrer une chaine par le clavier :");
String chaine = exemple.readLine();
System.out.println("la chaine saisie est "+chaine);
FileOutputStream fos = new FileOutputStream ( " theText.txt " );
PrintWriter myOutput = new PrintWriter ( fos );
myOutput . println ( chaine);
myOutput.close();
}
7. Les objets ObjectInputStream et ObjectOutputStream
Vous devez savoir que lorsqu'on veut écrire des objets dans des fichiers, on appelle ça la «
sérialisation » : Voici la classe avec laquelle nous allons travailler :
import java.io.Serializable;
public class Game implements Serializable{
private String nom, style;
private double prix;
public Game(String nom, String style, double prix) {
this.nom = nom; this.style = style; this.prix = prix; }
public String toString(){
return "Nom du jeu : " + this.nom + "\n Style de jeu : " + this.style + "\n Prix du jeu : "
+ this.prix + "\n"; }
Q11. Tester le rôle de cette classe et vérifier le fichier créé
import java.io.*;
public class testserialisation {
public static void main(String[] args) {
//Nous déclarons nos objets en dehors du bloc try/catch
ObjectInputStream ois; ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(
new File("game.txt"))));
//Nous allons écrire chaque objet Game dans le fichier
oos.writeObject(new Game("Assassin Creed", "Aventure", 45.69));
oos.writeObject(new Game("Tomb Raider", "Plateforme", 23.45));
oos.writeObject(new Game("Tetris", "Stratégie", 2.50));
//Ne pas oublier de fermer le flux !
oos.close();
//On récupère maintenant les données !
ois = new ObjectInputStream( new BufferedInputStream( new FileInputStream(
new File("game.txt"))));
try {
System.out.println("Affichage des jeux :");
System.out.println("*************************\n");
System.out.println(((Game)ois.readObject()).toString());
System.out.println(((Game)ois.readObject()).toString());
System.out.println(((Game)ois.readObject()).toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}}}