Flux, fichiers et E/S Java
Les flux, les fichiers et les E/S (entrées/sorties) en Java constituent l'infrastructure pour gérer la lecture et l'écriture de données. Ils permettent aux programmes d'interagir avec des données externes (telles que des fichiers, des réseaux, l'entrée système, etc.).
Le paquet java.io est un paquet central de la bibliothèque standard Java, fournissant des classes pour l'entrée et la sortie système. Il contient des outils pour gérer les flux de données (flux d'octets et flux de caractères), la lecture et l'écriture de fichiers, la sérialisation et le formatage des données.
java.io est le paquet fondamental pour gérer les opérations sur les fichiers, les opérations sur les flux et les opérations d'E/S de bas niveau.
Les flux du paquet java.io prennent en charge de nombreux formats, tels que les types primitifs, les objets, les jeux de caractères localisés, etc.
Un flux peut être compris comme une séquence de données. Un flux d'entrée représente la lecture de données depuis une source, et un flux de sortie représente l'écriture de données vers une destination.
Lecture de l'entrée console
L'entrée console en Java est gérée par System.in.
Pour obtenir un flux de caractères lié à la console, vous pouvez envelopper System.in dans un objet BufferedReader afin de créer un flux de caractères.
Voici la syntaxe de base pour créer un BufferedReader :
Après la création de l'objet BufferedReader, nous pouvons utiliser la méthode read() pour lire un caractère depuis la console, ou la méthode readLine() pour lire une chaîne.
Lecture de plusieurs caractères depuis l'entrée de la console
Pour lire un caractère à partir d'un objet BufferedReader, utilisez la méthode read(). Sa syntaxe est la suivante :
Chaque fois que la méthode read() est appelée, elle lit un caractère dans le flux d'entrée et renvoie le caractère sous forme de valeur entière. Elle renvoie -1 lorsque le flux se termine. Cette méthode lève une IOException.
Le programme suivant montre comment utiliser la méthode read() pour lire en continu des caractères depuis la console jusqu'à ce que l'utilisateur saisisseq。
Code du fichier BRRead.java :
Le résultat de compilation et d'exécution de l'exemple ci-dessus est le suivant :
输入字符, 按下 'q' 键退出。 example r u n o o b q q
Lecture de chaînes depuis l'entrée console
Pour lire une chaîne depuis l'entrée standard, vous devez utiliser la méthode readLine() de BufferedReader.
Son format général est :
Le programme suivant lit et affiche des lignes de caractères jusqu'à ce que vous saisissiez le mot "end".
Code du fichier BRReadLines.java :
Le résultat de compilation et d'exécution de l'exemple ci-dessus est le suivant :
Enter lines of text. Enter 'end' to quit. This is line one This is line one This is line two This is line two end end
Dans les versions après JDK 5, nous pouvons également utiliser la classeScannerde Java pour obtenir une entrée console.
Sortie console
Comme introduit précédemment, la sortie console est réalisée par print() et println(). Ces méthodes sont toutes définies par la classe PrintStream, et System.out est une référence à un objet de cette classe.
PrintStream hérite de la classe OutputStream et implémente la méthode write(). Ainsi, write() peut également être utilisée pour écrire dans la console.
La forme la plus simple de write() définie par PrintStream est la suivante :
Cette méthode écrit les huit bits de poids faible de byteval dans le flux.
Exemple
L'exemple suivant utilise write() pour afficher le caractère "A" suivi d'un saut de ligne à l'écran :
Code du fichier WriteDemo.java :
L'exécution de l'exemple ci-dessus affiche le caractère "A" dans la fenêtre de sortie.
A
Remarque :La méthode write() n'est pas fréquemment utilisée car les méthodes print() et println() sont plus pratiques à utiliser.
Lecture et écriture de fichiers
Comme mentionné précédemment, un flux est défini comme une séquence de données. Les flux d'entrée sont utilisés pour lire des données à partir d'une source, et les flux de sortie sont utilisés pour écrire des données vers une destination.
Le diagramme suivant est un diagramme de hiérarchie de classes décrivant les flux d'entrée et les flux de sortie.
Flux d'octets (gestion des données binaires)
Les flux d'octets sont utilisés pour traiter des données binaires, telles que des fichiers, des images, des vidéos, etc.
| Nom de classe | Type | Description |
|---|---|---|
InputStream | Classe abstraite (flux d'entrée) | La superclasse de tous les flux d'entrée d'octets, gérant les opérations d'entrée d'octets. |
OutputStream | Classe abstraite (flux de sortie) | La superclasse de tous les flux de sortie d'octets, gérant les opérations de sortie d'octets. |
FileInputStream | Flux d'entrée | Lit des données d'octets à partir d'un fichier. |
FileOutputStream | Flux de sortie | Écrit des données d'octets dans un fichier. |
BufferedInputStream | Flux d'entrée | Fournit une mise en mémoire tampon pour les flux d'entrée d'octets afin d'améliorer l'efficacité de lecture. |
BufferedOutputStream | Flux de sortie | Fournit une mise en mémoire tampon pour les flux de sortie d'octets afin d'améliorer l'efficacité d'écriture. |
ByteArrayInputStream | Flux d'entrée | Utilise un tableau d'octets en mémoire comme source d'entrée. |
ByteArrayOutputStream | Flux de sortie | Écrit des données dans un tableau d'octets en mémoire. |
DataInputStream | Flux d'entrée | Permet de lire des types de données primitifs Java depuis un flux d'entrée (tel queint、float、boolean)。 |
DataOutputStream | Flux de sortie | Permet d'écrire des types de données primitifs Java vers un flux de sortie. |
ObjectInputStream | Flux d'entrée | Lit des objets sérialisés depuis un flux d'entrée. |
ObjectOutputStream | Flux de sortie | Sérialise des objets et les écrit dans un flux de sortie. |
PipedInputStream | Flux d'entrée | Utilisé pour lire des données d'octets dans un tube, généralement avecPipedOutputStreamUtilisés ensemble. |
PipedOutputStream | Flux de sortie | Utilisé pour écrire des données d'octets dans un tube, généralement avecPipedInputStreamUtilisés ensemble. |
FilterInputStream | Flux d'entrée | Une classe wrapper pour les flux d'entrée d'octets, utilisée pour effectuer un filtrage sur d'autres flux d'entrée. |
FilterOutputStream | Flux de sortie | Une classe wrapper pour les flux de sortie d'octets, utilisée pour effectuer un filtrage sur d'autres flux de sortie. |
SequenceInputStream | Flux d'entrée | Combine plusieurs flux d'entrée en un seul flux d'entrée pour le traitement. |
Flux de caractères (traitement des données textuelles)
Les flux de caractères sont utilisés pour gérer des données textuelles, comme la lecture et l'écriture de chaînes ou l'écriture de chaînes ou
| Nom de classe | Type | Description |
|---|---|---|
Reader | Classe abstraite (flux d'entrée) | La superclasse de tous les flux d'entrée de caractères, gérant les opérations d'entrée de caractères. |
Writer | Classe abstraite (flux de sortie) | La superclasse de tous les flux de sortie de caractères, gérant les opérations de sortie de caractères. |
FileReader | Flux d'entrée | Lit des données de caractères depuis un fichier. |
FileWriter | Flux de sortie | Écrit des données de caractères dans un fichier. |
BufferedReader | Flux d'entrée | Fournit une mise en mémoire tampon pour les flux d’entrée de caractères, prend en charge la lecture ligne par ligne et améliore l’efficacité de lecture. |
BufferedWriter | Flux de sortie | Fournit une mise en mémoire tampon pour les flux de sortie de caractères, prend en charge l’écriture ligne par ligne et améliore l’efficacité d’écriture. |
CharArrayReader | Flux d'entrée | Utilise un tableau de caractères comme source d’entrée. |
CharArrayWriter | Flux de sortie | Écrit des données dans un tableau de caractères. |
StringReader | Flux d'entrée | Utilise une chaîne de caractères comme source d’entrée. |
StringWriter | Flux de sortie | Écrit des données dans un tampon de chaîne. |
PrintWriter | Flux de sortie | Flux de sortie de caractères pratique, prend en charge le vidage automatique et la sortie formatée. |
PipedReader | Flux d'entrée | Utilisé pour lire des données de caractères dans un pipe, généralement avecPipedWriterutilisé ensemble. |
PipedWriter | Flux de sortie | Utilisé pour écrire des données de caractères dans un pipe, généralement avecPipedReaderutilisé ensemble. |
LineNumberReader | Flux d'entrée | Flux d'entrée de caractères mis en tampon avec numéros de ligne, permettant de suivre le numéro de ligne en cours de lecture. |
PushbackReader | Flux d'entrée | Permet de repousser des caractères dans le flux après lecture, afin qu'ils puissent être lus à nouveau. |
Classes utilitaires (autres classes importantes)
Les classes utilitaires fournissent un support pour les fichiers, les répertoires et l'accès aléatoire aux fichiers.
| Nom de classe | Type | Description |
|---|---|---|
File | Opérations sur les fichiers et les répertoires | Utilisé pour représenter un fichier ou un répertoire, et fournit des opérations sur les fichiers telles que la création, la suppression, le renommage, etc. |
RandomAccessFile | Fichier à accès aléatoire | Prend en charge l'accès aléatoire aux fichiers, permettant de lire et d'écrire des données à n'importe quelle position dans le fichier. |
Console | Entrée/sortie de la console | Fournit une prise en charge des entrées et sorties pour la console système. |
Les deux flux importants qui seront abordés ensuite sontFileInputStreametFileOutputStream。
FileInputStream
Ce flux est utilisé pour lire des données depuis un fichier. Son objet peut être créé en utilisant le mot-clé new.
Il existe plusieurs constructeurs qui peuvent être utilisés pour créer des objets.
Vous pouvez utiliser un nom de fichier de type chaîne pour créer un objet de flux d'entrée afin de lire un fichier :
Vous pouvez également utiliser un objet fichier pour créer un objet de flux d'entrée afin de lire un fichier. Nous devons d'abord utiliser la méthode File() pour créer un objet fichier :
Une fois l'objet InputStream créé, vous pouvez utiliser les méthodes suivantes pour lire le flux ou effectuer d'autres opérations de flux.
| Méthode | Description | Exemple de code |
|---|---|---|
int read() | Lit un octet de données, la valeur de retour étant un entier compris entre 0 et 255. Renvoie -1 si la fin du flux est atteinte. | int data = inputStream.read(); |
int read(byte[] b) | Lit des octets depuis le flux d'entrée et les stocke dans le tableau d'octetsbet renvoie le nombre réel d'octets lus. Renvoie -1 si la fin du flux est atteinte. | byte[] buffer = new byte[1024]; int bytesRead = inputStream.read(buffer); |
int read(byte[] b, int off, int len) | Lit jusqu'àlenoctets depuis le flux d'entrée et les stocke dans le tableau d'octetsbdeoffà partir de la position de décalage, en renvoyant le nombre réel d'octets lus. Renvoie -1 si la fin du flux est atteinte. | byte[] buffer = new byte[1024]; int bytesRead = inputStream.read(buffer, 0, buffer.length); |
long skip(long n) | Ignore et supprimenoctets dans le flux d'entrée, en renvoyant le nombre réel d'octets ignorés. | long skippedBytes = inputStream.skip(100); |
int available() | Renvoie le nombre d'octets qui peuvent être lus (sans blocage). | int availableBytes = inputStream.available(); |
void close() | Ferme le flux d'entrée et libère toutes les ressources associées à ce flux. | inputStream.close(); |
void mark(int readlimit) | Définit une marque à la position actuelle dans le flux,readlimitest la limite supérieure du nombre d'octets qui peuvent être lus. | inputStream.mark(1024); |
void reset() | Repositionne le flux à la position de la dernière marque. S'il n'y a pas de marque ou si la marque est invalide, lèveIOException。 | inputStream.reset(); |
boolean markSupported() | Vérifie si le flux d'entrée actuel prend en chargemark()etreset()l'opération. | boolean isMarkSupported = inputStream.markSupported(); |
En plus de InputStream, il existe d'autres flux d'entrée. Pour plus de détails, reportez-vous au lien ci-dessous :
FileOutputStream
Cette classe est utilisée pour créer un fichier et écrire des données dans le fichier.
Si le fichier cible n'existe pas avant que le flux n'ouvre le fichier pour la sortie, le flux créera le fichier.
Il existe deux constructeurs qui peuvent être utilisés pour créer un objet FileOutputStream.
Utilisez un nom de fichier de type chaîne pour créer un objet de flux de sortie :
Vous pouvez également utiliser un objet fichier pour créer un flux de sortie afin d'écrire dans un fichier. Nous devons d'abord utiliser la méthode File() pour créer un objet fichier :
Après avoir créé l'objet OutputStream, vous pouvez utiliser les méthodes suivantes pour écrire dans le flux ou effectuer d'autres opérations sur le flux.
| Méthode | Description | Exemple de code |
|---|---|---|
void write(int b) | Écrit l'octet spécifié dans le flux de sortie ; les 8 bits de poids faible debseront écrits dans le flux. | outputStream.write(255); |
void write(byte[] b) | Écrit tous les octets du tableau d'octetsbvers le flux de sortie. | byte[] data = "Hello".getBytes(); outputStream.write(data); |
void write(byte[] b, int off, int len) | Écrit des octets à partir du tableau d'octetsben commençant au décalageoffen commençant àlenoctets vers le flux de sortie. | byte[] data = "Hello".getBytes(); outputStream.write(data, 0, data.length); |
void flush() | Vide le flux de sortie et force toutes les données mises en mémoire tampon à être écrites, en garantissant que les données sont immédiatement écrites vers la sortie cible. | outputStream.flush(); |
void close() | Ferme le flux de sortie et libère toutes les ressources associées à ce flux. Après fermeture, aucune autre écriture ne peut être effectuée. | outputStream.close(); |
En plus de OutputStream, il existe d'autres flux de sortie. Pour plus de détails, reportez-vous au lien ci-dessous :
Exemple
L'exemple suivant illustre l'utilisation de InputStream et OutputStream :
code du fichier fileStreamTest.java :
Le programme ci-dessus crée d'abord le fichier test.txt, écrit les nombres donnés dans le fichier sous forme binaire, et en même temps les affiche dans la console.
Comme le code ci-dessus utilise l'écriture binaire, des caractères illisibles peuvent apparaître. Vous pouvez utiliser l'exemple de code suivant pour résoudre le problème des caractères illisibles :
Code du fichier fileStreamTest2.java :
Fichiers et E/S
Il y a aussi quelques classes liées aux fichiers et aux E/S que nous devons connaître :
Répertoires en Java
Création de répertoires :
Il existe deux méthodes dans la classe File qui peuvent être utilisées pour créer des dossiers :
- mkdir( )La méthode crée un dossier. Elle renvoie true en cas de succès et false en cas d'échec. L'échec indique que le chemin spécifié par l'objet File existe déjà, ou que le dossier ne peut pas être créé parce que le chemin complet n'existe pas encore.
- mkdirs()La méthode crée un dossier et tous ses dossiers parents.
L'exemple suivant crée le dossier "/tmp/user/java/bin" :
Code du fichier CreateDir.java :
Compilez et exécutez le code ci-dessus pour créer le répertoire "/tmp/user/java/bin".
Remarque :Java distingue automatiquement les séparateurs de chemin de fichiers selon la convention sous UNIX et Windows. Si vous utilisez le séparateur (/) dans une version Windows de Java, le chemin peut toujours être résolu correctement.
Lecture des répertoires
Un répertoire est en fait un objet File qui contient d'autres fichiers et dossiers.
Si vous créez un objet File et qu'il s'agit d'un répertoire, alors l'appel de la méthode isDirectory() renverra true.
Vous pouvez extraire la liste des fichiers et dossiers qu'il contient en appelant la méthode list() sur cet objet.
L'exemple ci-dessous montre comment utiliser la méthode list() pour vérifier le contenu d'un dossier :
Code du fichier DirList.java :
Le résultat de la compilation et de l'exécution de l'exemple ci-dessus est le suivant :
目录 /tmp bin 是一个目录 lib 是一个目录 demo 是一个目录 test.txt 是一个文件 README 是一个文件 index.html 是一个文件 include 是一个目录
Suppression de répertoires ou de fichiers
Pour supprimer un fichier, vous pouvez utiliser la méthodejava.io.File.delete().
Le code suivant supprimera le répertoire/tmp/java/. Notez que lors de la suppression d'un répertoire, vous devez vous assurer qu'il n'y a pas d'autres fichiers dans ce répertoire pour le supprimer correctement ; sinon, la suppression échouera.
Structure du répertoire de test :
/tmp/java/ |-- 1.log |-- test
