devstory

Le Tutoriel de Java InputStream

  1. InputStream
  2. read()
  3. read(byte[])
  4. read(byte[], int, int)
  5. readAllBytes()
  6. readNBytes(int len)
  7. readNBytes(byte[] b, int off, int len)
  8. close()
  9. skip(long)
  10. transferTo(OutputStream)
  11. markSupported()
  12. mark(int)
  13. reset()

1. InputStream

InputStream est une classe dans le package java.io, qui est une classe de base représentant un flux de bytes (stream of bytes) obtenu au cours de la lecture d'une source de données, un fichier par exemple.
public abstract class InputStream implements Closeable
En règle générale, vous ne pouvez pas utiliser directement la classe InputStream, car il s'agit d'une classe abstraite, mais dans un cas particulier, vous pouvez utiliser l'une de ses sous-classes.
Observer un exemple de fichier texte encodé en UTF-8:
utf8-file-without-bom.txt
JP日本-八洲
UTF-8 utilise 1, 2, 3 ou 4 bytes pour stocker un caractère. L'image ci-dessous démontre les bytes dans le fichier susmentionné.
FileInputStream est une sous-classe d'InputStream utilisé pour lire les fichier et on recevra un flux de bytes (stream of bytes).
InputStream Methods
public static InputStream nullInputStream()

public abstract int read() throws IOException  

public int read(byte[] b) throws IOException  
public int read(byte[] b, int off, int len) throws IOException

public byte[] readAllBytes() throws IOException
public byte[] readNBytes(int len) throws IOException  
public int readNBytes(byte[] b, int off, int len) throws IOException  

public long skip(long n) throws IOException  
public int available() throws IOException  

public void close() throws IOException  
public synchronized void mark(int readlimit)  
public synchronized void reset() throws IOException  

public boolean markSupported()  
public long transferTo(OutputStream out) throws IOException

2. read()

public int read() throws IOException
La méthode read() est utilisée pour lire un byte. La valeur du byte renvoyé est un entier (integer) compris entre 0 et 255, ou renvoyé à -1 s'il a atteint la fin du flux.
Cette méthode sera bloquée jusqu'à ce que le byte soit disponible pour la lecture ou qu'une erreur d'IO se produise, ou ait atteint la fin du flux.
utf8-file-without-bom.txt
JP日本-八洲
Par exemple:
InputStream_read_ex1.java
package org.o7planning.inputstream.ex;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_read_ex1 {
    
    // Windows path: C:/somepath/utf8-file-without-bom.txt"
    private static final String filePath = "/Volumes/Data/test/utf8-file-without-bom.txt";

    public static void main(String[] args) throws IOException {
        // FileInputStream is a subclass of InputStream.
        InputStream is = new FileInputStream(filePath);

        int code;
        while((code = is.read()) != -1) {
            System.out.println(code + " " + (char)code);
        }
        is.close();
    }
}
Output:
74 J
80 P
230 æ
151 —
165 ¥
230 æ
156 œ
172 ¬
45 -
229 å
133 …
171 «
230 æ
180 ´
178 ²

3. read(byte[])

public int read(byte[] b) throws IOException
La méthode read(byte[]) lit les bytes à partir d'InputStream et assigne aux éléments du tableau et renvoie le nombre de bytes qui viennent d'être lus. Cette méthode renvoie à -1 s'il a atteint la fin du flux.
Cette méthode sera bloquée jusqu'à ce que les bytes sont disponibles à être lus ou une erreur d'IO se produise, ou ont atteint la fin du flux.
En règle générale, utiliser la méthode read(byte[]) donnera une meilleure performance que la méthode read(), car elle réduit le nombre de fois qu'elle doit lire à partir du flux.
InputStream_read_ex2.java
package org.o7planning.inputstream.ex;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class InputStream_read_ex2 {

    public static void main(String[] args) throws IOException {
        String url = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";

        InputStream is = new URL(url).openStream();

        // Create a temporary byte array.
        byte[] tempByteArray = new byte[10];
        int byteCount = -1;

        int nth = 0;
        while ((byteCount = is.read(tempByteArray)) != -1) {
            nth++;
            System.out.println("--- Read th: " + nth + " ---");
            System.out.println(" >> Number of bytes read: " + byteCount +"\n");
            
            for(int i= 0; i < byteCount; i++) {
                // bytes are in range [-128,127]
                // Convert byte to unsigned byte. [0, 255].
                int code = tempByteArray[i] & 0xff;
                
                System.out.println(tempByteArray[i] + "    " + code + "    " + (char)code);
            }
        }
        is.close();
    }
}
Output:
--- Read th: 1 ---
 >> Number of bytes read: 10

74    74    J
80    80    P
-26    230    æ
-105    151    —
-91    165    ¥
-26    230    æ
-100    156    œ
-84    172    ¬
45    45    -
-27    229    å
--- Read th: 2 ---
 >> Number of bytes read: 5

-123    133    …
-85    171    «
-26    230    æ
-76    180    ´
-78    178    ²
Remarque: Le type de données byte inclut les entiers (integer) compris entre -128 et 127. Vous pouvez le convertir en un entier non signé (unsigned integer) compris entre 0 et 255.
  • Convert byte to unsigned byte

4. read(byte[], int, int)

public int read(byte[] b, int offset, int len) throws IOException
La méthode read(byte[],int,int) lit les bytes et assigne aux éléments du tableau à partir de l'indice offset à celui d'offset+len, et renvoie le nombre de bytes qui viennent d'être lus. Cette méthode renvoie à -1 si elle a atteint la fin du flux.
Cette méthode sera bloquée jusqu'à ce que les bytes soient disponibles à être lus, ou une erreur d'IO se produise, ou ont atteint la fin du flux.

5. readAllBytes()

public byte[] readAllBytes() throws IOException
Par exemple:
InputStream_readAllBytes_ex1.java
package org.o7planning.inputstream.ex;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class InputStream_readAllBytes_ex1 {

    public static void main(String[] args) throws IOException {
        String url = "https://s3.o7planning.com/txt/utf8-file-without-bom.txt";

        InputStream is = new URL(url).openStream();

        byte[] allBytes = is.readAllBytes();
        String content = new String(allBytes, "UTF-8");
        System.out.println(content);

        is.close();
    }
}
Output:
JP日本-八洲

6. readNBytes(int len)

public byte[] readNBytes(int len) throws IOException
La méthode readNBytes(int) lit au maximum "len"bytes à partir d'InputStream, et renvoie un tableau de byte lu. Si un tableau renvoyé est vide, il a atteint la fin du flux.
Cette méthode sera bloquée jusqu'à ce que "len"bytes soit lu, ou une erreur d'IO se produise, ou a atteint la fin du flux.
Par exemple:
InputStream_readNBytes_ex1.java
package org.o7planning.inputstream.ex;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_readNBytes_ex1 {
    
    // Windows path: C:/somepath/utf8-file-without-bom.txt"
    private static final String filePath = "/Volumes/Data/test/utf8-file-without-bom.txt";

    public static void main(String[] args) throws IOException {
        // FileInputStream is a subclass of InputStream.
        InputStream is = new FileInputStream(filePath);

        byte[] bytes = null;
        int nth = 0;
        while( true) {
            nth++;
            bytes = is.readNBytes(10);
            
            System.out.println("--- Read th: " + nth + " ---");
            System.out.println(" >> Number of bytes read: " + bytes.length +"\n");
            
            
            if(bytes.length == 0) {
                break;
            }
            for(int i= 0; i< bytes.length; i++) {
                // bytes are in range [-128,127]
                // Convert byte to unsigned byte. [0, 255].
                int code = bytes[i] & 0xff;
                
                System.out.println(bytes[i] + "    " + code + "    " + (char)code);
            }
        }
        is.close();
    }
}
Output:
--- Read th: 1 ---
 >> Number of bytes read: 10

74    74    J
80    80    P
-26    230    æ
-105    151    —
-91    165    ¥
-26    230    æ
-100    156    œ
-84    172    ¬
45    45    -
-27    229    å
--- Read th: 2 ---
 >> Number of bytes read: 5

-123    133    …
-85    171    «
-26    230    æ
-76    180    ´
-78    178    ²
--- Read th: 3 ---
 >> Number of bytes read: 0

7. readNBytes(byte[] b, int off, int len)

public int readNBytes(byte[] b, int offset, int len) throws IOException
La méthode readNBytes(byte[],int,int) lit au maximum "len"bytes à partir d'InputStream, et assigne les bytes lus aux éléments du tableau à partir de l'indice offset à offset+len, et renvoie le nombre de bytes lus. Renvoyer à -1 s'il a atteint la fin du flux.
read(byte[],int,int) vs readNBytes(byte[],int,int)
public int read(byte[] b, int offset, int len) throws IOException  

public int readNBytes(byte[] b, int offset, int len) throws IOException
Les méthodes read(byte[],int,int) et readNBytes(byte[],int,int) sont pratiquement similaires. Mais, une différence peut se produire dans la situation ci-dessous:
La méthode read(byte[] b,int offset, int len) ne garantit pas que "len" bytes soit lu à partir du flux même s'il n'a pas atteint la fin du flux.
La méthode readNBytes(byte[] b,int offset, int len) garantit que "len" bytes soit lu à partir du flux s'il n'a pas encore atteint la fin du flux.

8. close()

public void close() throws IOException
Fermer le flux et libérer toutes les ressources système qui lui sont associées. Une fois le flux fermé, des invocations supplémentaires read(), mark(), reset() ou skip() lèveront une IOException. La fermeture d'un flux précédemment fermé n'a aucun effet.
public interface Closeable extends AutoCloseable
La classe InputStream implémente une interface Closeable. Si vous écrivez le code selon les règles d'AutoCloseable, le système fermera automatiquement le flux sans avoir à appeler directement la méthode close().
InputStream_close_ex1.java
package org.o7planning.inputstream.ex;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_close_ex1 {
    
    // Or Windows path: C:/Somefolder/utf8-file-without-bom.txt
    private static final String file_path = "/Volumes/Data/test/utf8-file-without-bom.txt";

    public static void main(String[] args) throws IOException {
        
        // (InputStream class implements Closeable)
        // (Closeable interface extends AutoCloseable)
        // try block will automatically close stream for you.
        try (InputStream fileInputStream= new FileInputStream(file_path)) {
            int code;
            while((code = fileInputStream.read()) !=  -1)  {
                System.out.println(code +"  " + (char)code);
            }  
        } // end try
    }
}
  • Le Tutoriel de Java Closeable

9. skip(long)

public long skip(long n) throws IOException
La méthode skip(long) saute "n"bytes.
Cette méthode sera bloquée jusqu'à ce que des bytes soient disponibles ou qu'une erreur d'IO se produise, ou ait atteint la fin du flux.
InputStream_skip_ex1.java
package org.o7planning.inputstream.ex;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_skip_ex1 {

    public static void main(String[] args) throws IOException {
        
        String s = "123456789-987654321-ABCDE";
        byte[] bytes = s.getBytes();
        
        // ByteArrayInputStream is a subclass of InputStream.
        InputStream is = new ByteArrayInputStream(bytes);

        int firstByteCode = is.read();
        int secondByteCode = is.read();

        System.out.println("First byte: " + (char) firstByteCode);
        System.out.println("Second byte: " + (char) secondByteCode);

        is.skip(18); // Skips 18 bytes.

        int code;
        while ((code = is.read()) != -1) {
            System.out.println(code +" " + (char) code);
        }
        is.close();
    }
}
Output:
First byte: 1
Second byte: 2
65 A
66 B
67 C
68 D
69 E

10. transferTo(OutputStream)

// Java 10+
public long transferTo(OutputStream out) throws IOException
La méthode transferTo(OutputStream) est utilisée pour lire tous les bytes de l'actuel InputStream et les écrire dans l'objet OutputStream spécifié, et renvoyer le nombre de bytes transférés vers OutputStream. Une fois terminé, l'objet InputStream actuel se trouvera à la fin du flux. Cette méthode ne fermera pas l'objet InputStream actuel ni l'objet OutputStream.
InputStream_transferTo_ex1.java
package org.o7planning.inputstream.ex;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class InputStream_transferTo_ex1 {

    public static void main(String[] args) throws IOException {
        String s = "123456789-987654321-ABCDE";
        byte[] bytes = s.getBytes();
        
        // ByteArrayInputStream is a subclass of InputStream.
        InputStream reader = new ByteArrayInputStream(bytes);

        // Or Windows path: C:/Somepath/out-file.txt
        File file = new File("/Volumes/Data/test/out-file.txt");
        // Create parent folder.
        file.getParentFile().mkdirs();

        OutputStream writer = new FileOutputStream(file);

        reader.skip(10); // Skips 10 bytes.

        reader.transferTo(writer);

        reader.close();
        writer.close();
    }
}
Output:
out-file.txt
987654321-ABCDE

11. markSupported()

public boolean markSupported()
La méthode markSupported() est utilisée pour vérifier si l'objet InputStream actuelle prend en charge l'opération mark(int) ou non.(Voir plus sur la méthode mark(int))

12. mark(int)

public void mark(int readAheadLimit) throws IOException
La méthode mark(int) vous permet de marquer la position actuelle sur le flux. Vous pouvez lire les bytes suivants et appeler la méthode reset() pour revenir à la position marquée précédemment, dans laquelle readAheadLimit est le nombre maximal de bytes susceptibles d'être lus après le marquage sans perdre la position marquée.
Remarque: Tous les InputStream ne prennent pas en charge l'opération mark(int). Pour s'assurer, il faut convoquer la méthode markSupported() pour vérifier si l'objet InputStream actuel prend en charge cette opération.
InputStream_mark_ex1.java
package org.o7planning.inputstream.ex;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class InputStream_mark_ex1 {

    public static void main(String[] args) throws IOException {
        
        String s = "123456789-987654321-ABCDE";
        byte[] bytes = s.getBytes(); // byte[]{'1','2', .... 'E'}
        
        // ByteArrayInputStream is a subclass of InputStream.
        InputStream is = new ByteArrayInputStream(bytes);


        is.skip(10); // Skips 10 bytes.

        System.out.println("ByteArrayInputStream markSupported? " + is.markSupported()); // true
        
        is.mark(9);
        
        int code1 = is.read();
        int code2 = is.read();
        
        System.out.println(code1 + "  " + (char) code1); // '9'
        System.out.println(code2 + "  " + (char) code2); // '8'
        is.skip(5);
        
        System.out.println("Reset");
        is.reset(); // Return to the marked position.
        
        int code;
        while((code = is.read())!= -1) {
            System.out.println(code + "  " + (char)code);
        }
        is.close();
    }
}
Output:
ByteArrayInputStream markSupported? true
57  9
56  8
Reset
57  9
56  8
55  7
54  6
53  5
52  4
51  3
50  2
49  1
45  -
65  A
66  B
67  C
68  D
69  E

13. reset()

public void reset() throws IOException
Si cet objet InputStream prend en charge le marquage de la position actuelle via la méthode mark(int), donc, la méthode reset() est utilisée pour revenir à la position maquée.

Tutoriels Java IO

Show More