betacode

Руководство 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 - это класс в package java.io, который является базовым классом, представляющим поток bytes (stream of bytes), полученный при чтении определенного источника данных, например файла.
public abstract class InputStream implements Closeable
В принципе, вы не можете использовать класс InputStream напрямую, потому что это абстрактный класс, но в конкретном случае вы можете использовать один из его подклассов.
Давайте рассмотрим пример текстового файла в кодировке UTF-8:
utf8-file-without-bom.txt
JP日本-八洲
UTF-8 использует 1, 2, 3 или 4 bytes для хранения символа. На рисунке ниже показаны bytes в вышеупомянутом файле.
FileInputStream - это подкласс InputStream, который обычно используется для чтения файлов, и мы получаем поток 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
Метод read() используется для чтения byte. Значение возвращаемого byte представляет собой целое число (integer) от 0 до 255 или возвращает -1, если оно достигло конца stream.
Этот метод будет блокироваться (block) до тех пор, пока byte не будет доступен для чтения, или не произойдет ошибка IO, или не достигнет конца stream.
utf8-file-without-bom.txt
JP日本-八洲
Например:
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
Метод read(byte[]) считывает bytes из InputStream и присваивает элементам массива и возвращает количество только что прочитанных bytes. Этот метод возвращает -1, если он достиг конца stream.
Этот метод будет блокироваться (block) до тех пор, пока bytes не станут доступны для чтения, или не произойдет ошибка IO, или пока не достигнет конца stream.
В принципе, использование метода read(byte[]) будет иметь более высокую производительность, чем метод read(), так как он уменьшает количество раз, необходимое для чтения из stream.
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    ²
Примечание: Тип данных byte включает целые числа в диапазоне от -128 до 127. Вы можете преобразовать его в целое число без знака (unsigned integer) в диапазоне от 0 до 255.
  • Convert byte to unsigned byte

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

public int read(byte[] b, int offset, int len) throws IOException
Метод read(byte[],int,int) считывает bytes и присваивает элементам массива от индекса offset до индекса offset+len и возвращает количество только что прочитанных bytes. Этот метод возвращает -1, если он достиг конца stream.
Этот метод будет блокироваться (block) до тех пор, пока bytes не станут доступны для чтения, или не произойдет ошибка IO, или не достигнет конца stream.

5. readAllBytes()

public byte[] readAllBytes() throws IOException
Например:
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
Метод readNBytes(int) считывает до "len"bytes из InputStream и возвращает прочитанный массив byte. Если возвращаемый массив пуст, он уже находится в конце stream.
Этот метод будет блокироваться (block) до тех пор, пока не будут прочитаны "len"bytes, или не произойдет ошибка IO, или не достигнет конца stream.
Например:
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
Метод readNBytes(byte[],int,int) считывает до "len"bytes из InputStream и присваивает прочитанные bytes элементам массива из индекса offset до индекса offset+len, и возвращает количество прочитанных bytes. Возвращает -1, если он достиг конца stream.
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
Два метода read(byte[],int,int) и readNBytes(byte[],int,int) очень похожи. Но есть разница в следующей ситуации:
Метод read(byte[] b,int offset, int len) не гарантирует, что "len" bytes будут считаны из stream, даже если он еще не достиг конца stream.
Метод readNBytes(byte[] b,int offset,int len) гарантирует, что "len" bytes будут считаны из stream, если он еще не достиг конца stream.

8. close()

public void close() throws IOException
Закрывать этот stream и освобождать все связанные с ним системные ресурсы. Как только stream будет закрыт, дальнейшие вызовы read(), mark(), reset() или skip() вызовут исключение IOException. Закрытие ранее закрытого stream не имеет никакого эффекта.
public interface Closeable extends AutoCloseable
Класс InputStream реализует интерфейс Closeable. Если вы пишете код в соответствии с правилами AutoCloseable, система автоматически закроет stream для вас, не вызывая метод 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
    }
}
  • Руководство Java Closeable

9. skip(long)

public long skip(long n) throws IOException
Метод skip(long) пропускает "n"bytes.
Этот метод будет блокироваться (block) до тех пор, пока не будут доступны bytes, не произойдет ошибка IO, или не достигнет конца stream.
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
Метод transferTo(OutputStream) используется для считывания всех bytes из текущего InputStream и записи их в указанный объект OutputStream, а также для возврата количества bytes, переданных в OutputStream. После этого текущий объект InputStream будет находиться в конце stream. Этот метод не закроет ни текущий объект InputStream, ни объект 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()
Метод markSupported() используется для проверки того, поддерживает ли текущий объект InputStream операцию mark(int). (См. также метод mark(int))

12. mark(int)

public void mark(int readAheadLimit) throws IOException
Метод mark(int) позволяет отметить текущую позицию в stream. Вы можете прочитать следующие bytes и вызвать метод reset(), чтобы вернуться в позицию, отмеченную ранее. При этом readAheadLimit - это максимальное количество bytes, которые могут быть прочитаны после маркировки без потери отмеченной позиции.
Примечание: Не все InputStream поддерживают операцию mark(int). Чтобы быть уверенным, вам нужно вызвать метод markSupported(), чтобы проверить, поддерживает ли текущий объект InputStream эту операцию.
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
Если этот объект InputStream поддерживает маркировку текущей позиции с помощью метода mark(int), то для возврата отмеченной позиции используется метод reset().
No ADS

Руководства Java IO

Show More