# Programmation Java/Entrées Sorties

* Introduction
* La notion de machine virtuelle
* Installation
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Premier programme
** Commentaires
** Types de base
** Opérateurs
** Conditions
** Bloc de portée
** Itérations
** Tableaux
* Les classes en Java
** Membres
** Modificateurs d'accès
** Héritage
** Encapsulation
** Polymorphisme
** Classes abstraites
** Interfaces
** Classes internes
** Transtypage
** Types génériques
** Instanciation et cycle de vie
** « this »
** Objets comparables et clés
** Énumérations
** Exceptions
** Packages
* Classes de base
** Collections
** Nombre de taille arbitraire
** Tags Javadoc
** Annotations
** Entrées sorties
** Threads et synchronisation
** Méthodes natives
** Réflexion
** Regex
** JUnit
* Conclusion
* Exemples en Java
** Générer un carré magique
** Générer un triangle de Sierpiński
** XML
** Swing
*** Un premier exemple
*** Formulaire avec boutons sur image
*** Calcul de somme
*** Calcul de distance
* Annexes
** Les outils de base fournis avec le Java Development Kit
** Créer une archive Java
** Paramétrer la JVM
** Liste des mots réservés
** Débogage
** Java et les autres langages
* Introduction
* La notion de machine virtuelle
* Installation
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Premier programme
** Commentaires
** Types de base
** Opérateurs
** Conditions
** Bloc de portée
** Itérations
** Tableaux
* Les classes en Java
** Membres
** Modificateurs d'accès
** Héritage
** Encapsulation
** Polymorphisme
** Classes abstraites
** Interfaces
** Classes internes
** Transtypage
** Types génériques
** Instanciation et cycle de vie
** « this »
** Objets comparables et clés
** Énumérations
** Exceptions
** Packages
* Classes de base
** Collections
** Nombre de taille arbitraire
** Tags Javadoc
** Annotations
** Entrées sorties
** Threads et synchronisation
** Méthodes natives
** Réflexion
** Regex
** JUnit
* Conclusion
* Exemples en Java
** Générer un carré magique
** Générer un triangle de Sierpiński
** XML
** Swing
*** Un premier exemple
*** Formulaire avec boutons sur image
*** Calcul de somme
*** Calcul de distance
* Annexes
** Les outils de base fournis avec le Java Development Kit
** Créer une archive Java
** Paramétrer la JVM
** Liste des mots réservés
** Débogage
** Java et les autres langages
[ Modifier le sommaire ]
Les opérations d'entrées-sorties concernent la lecture (entrée) et l'écriture (sortie) de données à travers différents types de flux...
En Java, les opérations d'entrées-sorties de base sont gérées par les classes du package java.io. Ces classes obéissent au patron de conception décorateur. Ces objets sont souvent créés au sein d'objets correspondant au patron de conception fabrique.

## Flux d'entrée-sortie

Le package java.io possède deux classes principales :
* InputStream : cette classe abstraite définit les fonctions de lecture (entrée ou input en anglais),
* OutputStream : cette classe abstraite définit les fonctions d'écriture (sortie ou output en anglais).
Ces deux classes abstraites définissent des fonctions bas-niveau et sont implémentées dans différentes sous-classes concrètes. Il y a plusieurs types de flux dont : les flux sur fichiers, les flux sur tubes, et les flux sur zones de mémoire. Par exemple on a :
* FileInputStream : lecture d'un fichier,
* FileOutputStream : écriture d'un fichier.
La classe java.net.Socket possèdent des méthodes retournant des instances concrètes des classes InputStream et OutputStream pour lire et écrire depuis/vers la socket TCP.

### java.io.InputStream

La classe java.io.InputStream possèdent des méthodes lisant une série d'octets (byte).
* int InputStream.read : lit un octet et retourne sa valeur (0 à 255) ou -1 pour signaler la fin de flux.
* int InputStream.read(byte b): lit b.length octets pour remplir le tableau, et retourne le nombre d'octets lus.
* int InputStream.read(byte b, int off, int len): lit len octets, et les dépose en commençant à b[off], et retourne le nombre d'octets lus
Les deux dernières méthodes lisent une série d'octets dans un tableau, mais peuvent retourner un nombre inférieur à celui demandé pour différentes raisons :
* -1 indique qu'aucun octet n'a pu être lu car la fin du flux a été atteinte.
* 0 indique qu'aucun octet n'a pu être lu temporairement, pas de données disponible (par exemple depuis une connexion réseau). Cela se produit pour les flux non bloquants.
* Un nombre positif mais inférieur à celui demandé s'il n'y en a pas plus pour le moment (connexion réseau) ou définitivement (fin du flux).

### java.io.OutputStream

La classe java.io.OutputStream possède des méthodes écrivant une série d'octets (byte).
* OutputStream.write: écrit un byte
* OutputStream.write(byte b): écrit b.length bytes.
* OutputStream.write(byte b, int off, int len): écrit len bytes, commencer à b[off].

### java.io.PrintStream

La classe java.io.PrintStream hérite de la classe java.io.OutputStream, et permet d'afficher tous les types de données sous forme textuelle.
La sortie standard et l'erreur standard impriment sur la console et sont des instances de la classe java.io.PrintStream.
Exemple :
Tout objet peut être affiché car les méthodes print et println appellent la méthode ToString définie dans la classe java.lang.Object racine de l'arbre hiérarchique de tous les types d'objets.
Exemple :
La méthode toString est également appelée implicitement lors de la concaténation de chaînes de caractères :
Il est donc important que cette méthode n'ait aucun effet de bord (modification d'un objet, synchronisation, ...).

## Lecture-écriture haut niveau

Le package java.io possède des classes permettant la lecture et l'écriture de différents types de données.

## Reader, Writer, PrintStream, Scanner

Pour intéragir avec l'utilisateur dans la console.
Exemple de saisie d'un tableau de noms utilisant la classe Scanner :

## Gestion des répertoires et des fichiers
### Type de chemin

Un chemin est une instance de la classe java.io.File et peut désigner :
* un fichier normal (La méthode isFile retourne true),
* un répertoire (La méthode isDirectory retourne true),
* un fichier spécial spécifique au système d'exploitation (pipe, device, chemin réseau UNC, ...).

### Résolution de chemin

Pour construire une instance de java.io.File à partir d'un chemin, utilisez le constructeur File(String path) :
Il peut s'agir d'un chemin relatif :
Pour créer un chemin relatif à celui d'un répertoire, utilisez le constructeur File(File dir, String path) :
Pour obtenir le chemin absolu, appelez la méthode getAbsoluteFile pour l'obtenir sous la forme d'un objet File, ou la méthode getAbsolutePath pour l'obtenir sous la forme d'une chaîne de caractères String.
Pour obtenir le chemin canonique, utilisez la méthode getCanonicalFile pour l'obtenir sous la forme d'un objet File, ou la méthode getCanonicalPath pour l'obtenir sous la forme d'une chaîne de caractères String. Le chemin canonique résout les liens symboliques et les deux méthodes peuvent donc lancer une exception en cas d'erreur (lien cassé).

### Lister les fichiers d'un répertoire

Pour les chemins désignant un répertoire, la méthode listFiles retourne un tableau des fichiers contenu dans le répertoire. Ce tableau n'inclut pas d'entrée pour . (répertoire courant) ni pour .. (répertoire parent).

### Lister les chemins racines

La méthode statique listRoots retourne un tableau des chemins racines du système de fichiers. Pour Linux, cette méthode retourne le répertoire racine /. Pour Windows, cette méthode retourne le répertoire racine \ de chaque lecteur disponible (ex: C:\ D:\ ...).
Cette méthode est particulièrement utile pour créer un sélecteur de fichiers utilisant un arbre de répertoires.

### Création d'un répertoire

Pour créer un dossier :
Pour créer un dossier récursivement (avec ses parents), remplacer mkdir par mkdirs.

### Création d'un fichier temporaire

Pour créer un fichier temporaire, utilisez la méthode statique createTempFile(prefix, suffix, directory).

#### prefix

    Préfixe du nom de fichier.

#### suffix

    Suffixe du nom de fichier.

#### directory

    Répertoire où créer le fichier, ou null pour le créer dans le répertoire temporaire du système.
La méthode retourne le chemin du fichier créé ; le nom contient un identifiant unique.
La variante createTempFile(prefix, suffix) équivaut à appeler la même méthode avec null pour directory : elle crée un fichier dans le répertoire temporaire du système.
La suppression n'est pas gérée par cette méthode. Utilisez la méthode deleteOnExit sur le fichier créé pour qu'il soit supprimé automatiquement à la fin de l'application. Il n'est pas possible d'annuler la requête de suppression de fichier en fin d'exécution.
Exemple :

### Copie

Pour copier un dossier (avec son contenu) :
Sans la bibliothèque Apache :

### Suppression

Pour un répertoire vide, ou un fichier :
Pour un répertoire vide ou non, ou un fichier :
Sans la bibliothèque Apache :

## Exemples concrets de flux
### Fichiers textes

Pour lire un fichier texte plusieurs fois en reprenant du début, il faut introduire une variable de type FileChannel, uniquement pour repositionner le lecteur :

### Images

Le paquetage javax.imageio contient des classes permettant la lecture et l'écriture d'images en utilisant des flux d'entrées-sorties génériques (java.io.InputStream et java.io.OutputStream), des flux d'images (javax.imageio.ImageInputStream et javax.imageio.ImageOutputStream) ou simplement un chemin de fichier (java.io.File).
Exemple convertissant une image GIF en PNG :
La classe ImageIO possède également une méthode read acceptant un flux de classe java.io.InputStream. Ce flux peut être créé à partir d'une connexion réseau ou de ressources locales au paquetage d'une classe de l'application.
La lecture crée un fichier temporaire dans le répertoire par défaut (méthode createTempFile de la classe java.nio.file.Files). Il est possible d'obtenir une exception avec le message can’t create cache file si la création échoue. Si l'application a été lancée par une autre application Java, le problème peut venir de la non transmission des variables d'environnement du système au processus créé, car celles-ci contiennent le chemin du répertoire des fichiers temporaires. Par défaut, sous Windows, le répertoire C:\Windows est utilisé mais l'écriture n'y est pas autorisé.

### Consoles

Les applications sur la plupart des systèmes d'exploitation (Windows, Linux, Android, ...) sont associées à trois flux standards connectés par défaut à la console, mais pouvant être redirigés depuis le shell ou par une application vers un autre flux (un fichier, un flux d'une autre application, ...).
En java ces flux sont disponibles dans la classe java.lang.System :

#### in

    Flux d'entrée standard de classe java.io.InputStream, utilisé pour lire une valeur entrée par l'utilisateur si le flux est relié à la console.

#### out

    Flux de sortie standard de classe java.io.PrintStream, que l'application utilise pour afficher un résultat.

#### err

    Flux d'erreur standard de classe java.io.PrintStream, que l'application utilise pour afficher des messages d'erreur.

### Réseaux
## Références

* ↑ (en) « I/O from the Command Line »
* ↑ (anglais) https://community.oracle.com/thread/1758088?start=0&tstart=0