13.    Les flux d'entrées – sorties 

Les classes d'entrée – sorties en Java sont placées principalement dans deux packages - java.io, qui est basé sur des flux (stream) et java.nio qui est basé sur des tampons (buffers) et des canaux (channels). 
Le flux est une séquence d'octets de longueur indéterminée. Le flux d'entrée importe des données dans le programme depuis une source externe. Le flux de sortie exporte des données vers une source externe. Les deux classes principales pour les flux sont java.io.InputStream et java.io.OutputStream. 
Toutes les instructions d'entrées – sorties lèvent "checked" exceptions





13.1    Les flux d'octets

Les méthodes principales des classes InputStream et OutputStream sont:

public abstract int read( ) throws IOException    //lit un octet et retourne un valeur entier entre 0 et 255
public abstract void write(int b) throws IOException    // ecrit un octer

pour un tableau entier
public int read(byte[] data) throws IOException
public void write(byte[] data) throws IOException

pour une partie du tableau:
public int read(byte[] data, int offset, int len) throws IOException
public void write(byte[] data, int offset, int len) throws IOException

Pour tester, téléchargez dans le répertoire du projet un petit fichier -  par ex   icon.png  from https://ff.tu-sofia.bg/JTech/go-back-icon.png
et un plus gros fichier - par ex. test.mp4  from https://jsoncompare.org/LearningContainer/SampleFiles/Video/MP4/Sample-MP4-Video-File-Download.mp4


Copier un fichier
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FCopy {
    public static void main(String arg[]) throws IOException{
        int bt;
        if(arg.length!=2){
            System.out.println("Usage: FCopy fileSource fileDestination");
            return;
        }
        String fns = arg[0], fnd = arg[1];
        System.out.println("copy the file "+fns+" in the file "+fnd);
        FileInputStream fi = null;
        FileOutputStream fo = null;
        try {
            fi = new FileInputStream(fns);
            fo = new FileOutputStream(fnd);
            while((bt = fi.read())!=-1)fo.write(bt);
            System.out.println("file "+fns+" is copied as "+fnd);
        }
        catch(FileNotFoundException ex){
            System.out.println("Thе file "+fns+" does not exist");
        }
        finally{
            if(fi != null)fi.close();
            if(fo != null)fo.close();
        }
    }
}

En utilisant des blocs:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FCopyArr {
    public static void main(String arg[]) throws IOException{
        byte bt[] = new byte[2048];
        int len;
        if(arg.length!=2){
            System.out.println("Usage: FCopy fileSource fileDestination");
            return;
        }
        String fns = arg[0], fnd = arg[1];
        System.out.println("copy the file "+fns+" in the file "+fnd);
        FileInputStream fi = null;
        FileOutputStream fo = null;
        try {
            fi = new FileInputStream(fns);
            fo = new FileOutputStream(fnd);
            while((len = fi.read(bt))!=-1){
                fo.write(bt,0,len);
            }
            System.out.println("file "+fns+" is copied as "+fnd);
        }
        catch(FileNotFoundException ex){
            System.out.println("The file "+fns+" does not exist");
        }
        finally{
            if(fi != null)fi.close();
            if(fo != null)fo.close();
        }
    }
}


13.2    Les flux de caractères

Classes Reader et Writer .

public int read()   throws IOException
public int read(char[] cbuf)   throws IOException
public abstract int read(char[] cbuf, int off, int len) throws IOException

void     write(int c) throws IOException
public void write(char[] cbuf)    throws IOException
abstract void     write(char[] cbuf, int off, int len) throws IOException
void     write(String str) throws IOException
void     write(String str, int off, int len) throws IOException

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FcharCopy {
    public static void main(String arg[]) throws IOException{
        int bt;
        if(arg.length!=2){
            System.out.println("Usage: FCopy fileSource fileDestination");
            return;
        }
        String fns = arg[0], fnd = arg[1];
        System.out.println("copy the file "+fns+" in the file "+fnd+"\n");
        FileReader fi = null;
        FileWriter fo = null;
        try {
            fi = new FileReader(fns);
            fo = new FileWriter(fnd);
            while((bt = fi.read())!=-1){
                fo.write(bt);
                System.out.print((char)bt);
            }
            System.out.println("\n\nfile "+fns+" is copied as "+fnd);
        }
        catch(FileNotFoundException ex){
            System.out.println("The file "+fns+" does not exist");
        }
        finally{
            if(fi != null)fi.close();
            if(fo != null)fo.close();
        }
    }
}


13.3    Les flux de lignes

Les classes BufferedReader et  PrintWriter

inputStream =  new BufferedReader(new FileReader("test.txt"));
outputStream =  new PrintWriter (new FileWriter("output.txt"));

L'exemple suivant fait la démonstration de ces classes pour copier un fichier.

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class FlineCopy {
    public static void main(String arg[]) throws IOException{
        String line = null;       
        String fns=null, fnd=null;
        BufferedReader sin=null;
        BufferedReader fi = null;
        PrintWriter fo = null;
        try {
            sin= new BufferedReader(new InputStreamReader(System.in));
            System.out.print("input the name of the source file:");
            fns = sin.readLine();
            System.out.print("input the name of the destination file:");
            fnd = sin.readLine();
            System.out.println("copy the file "+fns+" in the file "+fnd+"\n");
            fi = new BufferedReader(new FileReader(fns));
            fo = new PrintWriter(new FileWriter(fnd));
            while((line = fi.readLine())!= null){
                System.out.println(line);
                fo.println(line);
            }
            System.out.println("\n\nfile "+fns+" is copied as "+fnd);
        }
        catch(FileNotFoundException ex){
            System.out.println("The file "+fns+" does not exist");
            System.out.println("or the file "+fnd+" can not be created");
        }
        finally{
            if(fi != null)fi.close();
            if(fo != null)fo.close();
        }
    }
}


13.4    Les flux d'objets

Les flux enveloppes ObjectInputStream et ObjectOutputStream sont utilisés pour la sérialisation et la désérialisation des objets

ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("save.ser"));
ObjectOutputStream oos =  new ObjectOutputStream (new FileOutputStream ("save.ser"));

Les deux méthodes principales sont writeObject() et readObject(). Une conversion explicite vers le type d'objet est nécessaire pendant son reconstruction.
Un objet pourrait être sérialisé à condition que sa classe implémente l'interface Serializable.

Les classes:

import java.io.Serializable;
public class PersonSr implements Serializable{
    static int num=0;
    String name;
    String id;
    PersonSr(){
        name = "student "+ ++num;
        id = (int)(Math.random()*3999)+1111+"";
    }
}   
public class StudentSr extends PersonSr{
    int notes[];
    StudentSr(){
        notes = new int [5];
        for(int i =0;i<notes.length;i++){
            notes[i]=(int)(Math.random()*5)+2;
        }
    }
    public String toString(){
       String rez;
            rez = "name:"+name+"\tid:"+id+"\tnotes:";
        for(int i=0;i<notes.length;i++){
            rez += "\t"+notes[i];
        }
        return rez;       
    }
}

Serialisation:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class StudWr {
    public static void main(String arg[]) throws IOException{
        ObjectOutputStream oos = null;
        StudentSr s;
        try{
            oos = new ObjectOutputStream (
                new FileOutputStream ("save.ser"));
            for(int i=0;i<9;i++){
                s =new StudentSr();
                System.out.println(""+s);
                oos.writeObject(s);
            }
        }
        finally{
            oos.close();
        }
    }
}

Deserialisation

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectInputStream;
public class studRd {
    public static void main(String[] arg)throws
             IOException,ClassNotFoundException{
        ObjectInputStream ois = null;
        StudentSr s;
        int n=0, nf=0;
        try{
            ois = new ObjectInputStream (
                new FileInputStream ("save.ser"));
            for(;;){
                s= (StudentSr)ois.readObject();
                n++;
                if(average(s)>=4){
                    System.out.print(""+s);
                    System.out.println("\thas average "+ average(s));
                    nf++;
                }
            }
        }
        catch(EOFException ex){
            System.out.println("printed "+nf+" students, found total "+n+" students");
        }
        finally{
            ois.close();
        }
    }
    public static double average(StudentSr s){
        double sum;
        int i;
        for(sum=i=0;i<s.notes.length;i++){
            sum+=s.notes[i];
        }
        return sum/s.notes.length;
    }
}


13.5    La classe File

La classe File contient des méthodes de manipulation des fichiers et des répertoires.

Le premier exemple affiche sur la console le contenu d'un répertoire

import java.io.*;
public class FileLst{
    public static void main(String args[]) {
        try{
            File path = new File(args[0]);
            String[] list = path.list();
            for(int i = 0; i < list.length; i++)
                System.out.println(list[i]);
        }
        catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("there is no command line parameter");
        }
        catch (NullPointerException ex) {
            System.err.println("The directory does not exist");
        }
    }
}

Le deuxième exemple affiche sur la console les paramètres d'un répertoire (donné comme paramètre sur la ligne de commande).

import java.io.*;
import java.util.*;
public class FileInf{
    public static void main(String args[]) {
        File f;
        try{
            f = new File(args[0]);
        }   
        catch (ArrayIndexOutOfBoundsException e) {
            System.err.println("there is no command line parameter");
            return;
        }
        if(!f.exists()){
            System.err.println("The "+f+" does not exist");
            return;
        }
        System.out.println(
                " Abs path: " + f.getAbsolutePath() +
                "\n can write: " + f.canWrite() +
                "\n can read: " + f.canRead() +
                "\n Name: " + f.getName() +
                "\n Parent " + f.getParent() +
                "\n Path: " + f.getPath() +
                "\n Modif: " + new Date(f.lastModified()));
        if(f.isFile())
            System.out.println("This is a file with length "+ f.length() + " bytes");
        else if(f.isDirectory())
            System.out.println("This is a directory");
    }
}

 Le dernier exemple montre comment créer, supprimer et changer le nom d'un fichier:

import java.io.*;
public class FileManip{
    public static void main(String args[]){
        File newF = new File("D:\\tst\\Test.txt");
        File chng = new File("D:\\tst\\Test_change.txt");
        File dir1 = new File("D:\\tst\\Text.txt");    
        if(dir1.mkdirs()){
            System.out.println("Directory "+dir1+" created");
        }
        else {
            System.out.println("Directory "+dir1+" exist yet");
        }
        try{
            if(newF.createNewFile()){
                System.out.println("File  "+newF+" created");
            }
            else{
                System.out.println("File  "+newF+" exist yet");
            }
        }catch (IOException e) {
            System.out.println("the path to file "+ newF + "does not exist" );
        }
        if(newF.renameTo(chng)){
            System.out.println("File  "+newF+" renamed to" + chng);
        }
        else {
            System.out.println("File  "+newF+" does not exist");           
        }
        if (chng.delete()){
            System.out.println("File  "+ chng + " deleted");
        }
        else {
            System.out.println("File  "+chng + "can not be deleted");
        }
        if(dir1.delete()){
            System.out.println("Directory " + dir1 + " deleted"); 
        }
        else {
            System.out.println("Directory " + dir1 + " can not be deleted");
        }
    }
}