0 Généralités sur les fichiers
1 Classe File et parcours du système de fichiers
2 Manipulation des fichier textes : écriture et lecture
3 Flux d'objets-serialisation
4 CSV
5 XML
La notion de flux est très générale. Dans System.out.println, l'attribut out de la classe System est un flux de sortie.
La notion de flux de sortie est très générale en java ou en C++ : elle renvoie à n'importe quel "canal" suceptible de recevoir de l'information sous forme
d'une suite d'octets. Il peut s'agir d'un périphérique d'affichage comme avec l'objet out, mais il peut aussi s'agir d'un fichier ou d'une connexion à un site.
Deux grands types de flux : les flux binaires et les flux textes. Dans le second cas, l'information du flux est modifiée pour que la transmission soit celle
d'une suite de caractères (on parle de formatage).
Cette distinction se retrouve entre les différents flux sur fichiers. Il existe deux types de fichiers : les fichiers binaires et les fichiers text.
Pour ces derniers, on peut les ouvrir avec un éditeur de texte et avoir un résultat "interprétable" (que le fichier soit enregistré au format .txt, .xml,
.java etc...) tandis que l'ouverture d'un fichier binaire dans un éditeur de texte donne un résultat illisible (essayer d'ouvrir un .exe dans un éditeur
de texte par exemple).
On ne propose pas d'aller plus avant dans le développement des disinctions : le cours se place à un niveau pratique. En l'occurence,
Java propose des objets d'assez haut niveau pour que beaucoup des difficultés restent transparentes.
L'identification des fichiers se fait par un chemin absolu. Ces chemins se manipulent comme les String.
Noter que pour les chaînes, la manipulation du caractère \ se fait par '\\' au sein des chaînes. Donc pour désigner
le fichier c:\Documents\Recents\MonTexte.txt,
on récupère le chemin : String chemin="c:\\Documents\\Recents\\MonTexte.txt";.
Attention, le séparateur de noms de repertoires change en fonction de
votre système d'exploitation : \ sous Windows, mais / sous Unix ou Linux. Pour créer un code ne dépendant pas d'une plateforme ou de l'autre :
utiliser File.separator qui sera initialisé en fonction du système sur lequel le programme tourne. Par exemple, plutôt que :
String chemin="c:\\Documents\\Recents\\MonTexte.txt";, on peut mettre
String chemin="c:"+File.separator+"Documents"+File.separator+"Recents"+File.separator+"MonTexte.txt";.
La classe File permet d'instancier des objets qui réferencent aussi bien des répertoires que des fichiers.
On l'utilise pour le parcours et la manipulation du système de fichiers.
On crée un objet avec le passage d'une chaîne en paramètre, cette chaîne désigne un repertoire ou un fichier :
String chemin="c:\\etud\\"; File fichier=new File(chemin)
public void fonctionManipulationFile(File fichier) { if(fichier.isDirectory()) ... }
public void appelMaFonction() { try { instruction à exécuter maFonction(4,5); instruction à exéctuer }catch(Exception){Les instructions exécutées en cas d'Exception déclenchée lors de l'exécution de maFonction} }Exception est une interface pour laquelle il est possible de créer des sous-classes, par exemple, le fait d'introduire une division par 0 déclenche une ArithmeticException. Si l'Exception n'est pas traitée (récupérée par try{...}catch(){...}) : le code s'arretera. le thème sera traité de manière plus importante dans un cours suivant.
public static void ecrireFichier(FileOutputStream stream,String s) { try{ stream.write(s.getBytes()); }catch(Exception e){System.out.println("Exception in ecrireFichier(FileOutputStream)");} }Il suffit ensuite d'ouvrire un flux FileOutputStream puis on écrit des Sting dans ce fichier en appellant des fonctions ecrireFichier(fos,chaine); Par exemple (à exécuter puis observer le fichier c:\Mon Document.txt" :
import java.io; public class TestEcriture{ public static void main(String[] args) { FileOutputStream fos=null; try { fos=new FileOutputStream("c:\\Mon document.txt"); }catch(Exception e){System.out.println("Declenchement d'Exception : fonction main de TestEcriture");} TestEcriture.ecrireFichier(fos,"Un premier exemple d'ecriture de fichier"); TestEcriture.ecrireFichier(fos,"\n"); /*Fermeture du flux nécessaire : cf les exercices*/ try { fos.close(); }catch(Exception e){System.out.println("Declenchement d'Exception : fonction main de TestEcriture");} } public static void ecrireFichier(FileOutputStream stream,String s) { try{ stream.write(s.getBytes()); }catch(Exception e){System.out.println("Exception in ecrireFichier(FileOutputStream)");} } }
public static void main(String[] args) { byte[] tab=null; try { /*Ouverture du flux*/ FileInputStream fis=new FileInputStream("c:\\MonDoc.txt"); /*Creation du tableau de la taille le nombre de caractère du fichier*/ tab=new byte[fis.available()]; /*Le flux des octets du fichiers est mis dans le tableau*/ fis.read(tab); }catch(Exception e){System.out.println("Exception dans main");} if(tab!=null && tab.length>=5) { System.out.println("Les 5 premiers caracteres du fichier : "); for(int i=0;i<5;i++) { /*Obtention d'un caractère à partir de l'octet*/ char c=(char)tab[i]; /*Affichage*/ System.out.print(i+" "+c+"\t"); } } }
/*Affecte 5 à t*/ int t=Integer.parseInt("5"); /*Autres exemple d'affectation :*/ String str="65.7898"; String str2="100E-6"; double x1=Double.parseDouble(str); double x2=Double.parseDouble(str2); System.out.println((x1+x2))/*Cette derniere instruction affiche 65.7899*/
String chaineALire="1997-04-21"; SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); Date dt = fmt.parse(chaineALire); GregorianCalendar gC=(GregorianCalendar)fmt.getCalendar(); gC.setTime(dt);
La sérialisation consiste en l'enregistrement d'objet dans des fichiers binaires. Un objet doit implémenter l'interface java.io.Serializable
pour pouvoir être placé dans un fichier.
Utilisation de ObjectOutputStream ensuite pour avoir manipulation de l'objet : création d'un flux de sortie d'objet.
Exemple d'enregistrement d'objet dans un fichier :
try { FileOutputStream out=new FileOutputStream("File"); ObjectOutputStream s=new ObjectOutputStream(out); String str="Today"; s.writeObject(str); s.writeObject(new Date()); s.flush(); s.close(); }catch(Exception e){}Le code précédent entraîne la création d'un fichier File sur le disque dur (on pourrait spécifier un chemin absolu).
try { FileInputStream in=new FileInputStream("File"); ObjectInputStream s=new ObjectInputStream(in); /*Le programmeur peut transtyper puisque qu'il sait l'ordre des types des objets enregistrés*/ String str=(String)s.readObject(); Date dt=(Date)s.readObject(); }catch(Exception e){}
Pour la création de fichiers CSV : on crée un fichier texte et on organise le fichier en séparant les données avec un séparateur (la virgue) et en les
organisant en ligne.
On suppose avoir une liste listePersonnes d'objets de la classe Personne et une fonction d'écriture sur un FileOutputStream (voir 8.2) :
ecrireFichierTxt(FileOutputStream,String). On peut alors créer un fichier CSV :
public static void createCSV(FileOutputStream fos,LinkedList listePersonnes) { for(int i=0;i<listePersonnes.size();i++) { Personne per=(Personne)listePersonnes.get(i); ecrireFichier(fos,per.getName()+","+per.getSurname()+","+getAge()+","+getPatrimoine()+"\n"); } }
public static void cours(String fichier,MyDate dateRef) { CSVReader csvR; Double coursDateRef=null; String[] tab; try { csvR=new CSVReader(new FileReader(fichier),','); tab=csvR.readNext(); }catch(Exception e){System.out.println("Probleme pour lecture Reader");} }
On n'évoque pas ici la manipulation des fichiers XML. Elle se fait avec le package javax.swing.xml.parsers;