betacode

Руководство Java Reader

  1. Reader
  2. read()
  3. read(char[])
  4. read(char[], int, int)
  5. read(java.nio.CharBuffer)
  6. close()
  7. skip(long)
  8. transferTo(Writer)
  9. markSupported()
  10. mark(int)
  11. reset()
  12. ready()

1. Reader

Reader - это класс в package java.io, который является базовым классом, представляющим поток символов (stream of characters), полученных при чтении определенного источника данных, например текстового файла.
public abstract class Reader implements Readable, Closeable
В принципе, вы не можете использовать класс Reader напрямую, потому что это абстрактный класс. Но в конкретном случае вы можете использовать один из его подклассов.
Давайте рассмотрим сценарий чтения текстового файла с кодировкой UTF-8:
utf-8-file.txt
JP日本-八洲
UTF-8 использует 1, 2, 3 или 4 bytes для хранения символа. На рисунке ниже показаны bytes в вышеупомянутом файле.
FileReader - это подкласс Reader, обычно используемый для чтения текстовых файлов, и мы получим поток символов (stream of characters). Каким-то образом символы UTF-8 будут преобразованы в символы Java.
Примечание: тип char (символ)в Java имеет размер 2 bytes.Таким образом, символы в FileReader являются символами с размером 2 bytes.
См. Также мое объяснение того, как Java преобразует символы UTF-8 в символы Java:
Reader Methods
public static Reader nullReader()   

public int read(java.nio.CharBuffer target) throws IOException  

public int read() throws IOException  

public int read(char cbuf[]) throws IOException  

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

public long skip(long n) throws IOException  

public boolean ready() throws IOException   

public boolean markSupported()  

public void mark(int readAheadLimit) throws IOException  

public void reset() throws IOException   

public void close() throws IOException  

public long transferTo(Writer out) throws IOException

2. read()

public int read() throws IOException
Метод read() используется для чтения символов, который возвращает количество только что прочитанных символов (целое число от 0 до 65535) или -1, если он достиг конца stream (потока).
Этот метод будет блокироваться (block) до тех пор, пока не появится доступный символ или ошибка IO или не достигнет конца stream.
Например:
Reader_read_ex1.java
package org.o7planning.reader.ex;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Reader_read_ex1 {

    public static void main(String[] args) throws IOException {
        // StringReader is a subclass of Reader.
        Reader reader = new StringReader("JP日本-八洲");

        int charCode;
        while((charCode = reader.read()) != -1) {
            System.out.println((char)charCode + " " + charCode);
        }
        reader.close();
    }
}
Output:
J 74
P 80
日 26085
本 26412
- 45
八 20843
洲 27954

3. read(char[])

public int read(char[] cbuf) throws IOException
Метод read(char[]) считывает символы, присваивает элементы массива и возвращает количество только что прочитанных символов. Этот метод возвращает -1, если он достиг конца stream.
Этот метод будет блокироваться (block) до тех пор, пока символы не будут доступны, или не произойдет ошибка IO, или не достигнет конца stream.
В принципе, использование метода read(char[]) будет иметь лучшую производительность, чем метод read(), так как он уменьшает количество раз, необходимое для чтения из stream.
Reader_read_ex1.java
package org.o7planning.reader.ex;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Reader_read_ex2 {

    public static void main(String[] args) throws IOException {
        // StringReader is a subclass of Reader.
        Reader reader = new StringReader("123456789-987654321-12345");
 
        // Create a temporary char array.
        char[] temp = new char[10];
        int charCount = -1;
         
        while ((charCount = reader.read(temp)) != -1) {
            String s = new String(temp, 0, charCount);
            System.out.println(s);
        }
        reader.close();
    }
}
Output:
123456789-
987654321-
12345

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

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

5. read(java.nio.CharBuffer)

public int read(java.nio.CharBuffer target) throws IOException
Метод read(CharBuffer) используется для считывания символов в объект CharBufffer и возвращает количество символов, считанных из stream, или возвращает -1, если он достиг конца stream.
Этот метод будет блокироваться (block) до тех пор, пока символы не будут доступны, или не произойдет ошибка IO, или не достигнет конца stream.
Reader_read_ex3.java
package org.o7planning.reader.ex;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;

public class Reader_read_ex3 {

    public static void main(String[] args) throws IOException {
        // StringReader is a subclass of Reader.
        Reader reader = new StringReader("123456789-987654321-12345");
 
        CharBuffer cb = CharBuffer.allocate(10);
    
        // Read for the first time
        reader.read(cb);
        System.out.println(cb.flip().toString());
        
        // Read for the second time
        reader.read(cb);
        System.out.println(cb.flip().toString());
        
        // Read for the third time.
        reader.read(cb);
        System.out.println(cb.flip().toString());
        
        reader.close();  
    }
}
Output:
123456789-
987654321-
12345
  • Руководство Java CharBuffer

6. close()

public void close() throws IOException
Закрывать этот stream и освобождать все связанные с ним системные ресурсы. Как только stream будет закрыт, дальнейшие вызовыread(), ready(), mark(), reset() или skip() будут создавать исключение IOException. Приэтом действие по закрытию ранее закрытого stream не имеет никакого эффекта.
public interface Closeable extends AutoCloseable
Класс Reader реализует интерфейс Closeable. Если вы пишете код в соответствии с правилами AutoCloseable, система автоматически закроет stream для вас, не вызывая метод close() напрямую.
Reader_close_ex1.java
package org.o7planning.reader.ex;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Reader_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 {
        
        // (Reader class implements Closeable)
        // (Closeable interface extends AutoCloseable)
        // try block will automatically close stream for you.
        try (Reader fileReader= new FileReader(file_path)) {
            int code;
            while((code = fileReader.read()) !=  -1)  {
                System.out.println((char)code);
            }
        } // end try
    }
}
  • Руководство Java Closeable

7. skip(long)

public long skip(long n) throws IOException
Метод skip(long) пропускает символы "n".
Этот метод будет блокироваться (block) до тех пор, пока символы не будут доступны, или не произойдет ошибка IO, или не достигнет конца stream.
Reader_skip_ex1.java
package org.o7planning.reader.ex;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Reader_skip_ex1 {

    public static void main(String[] args) throws IOException {
        // StringReader is a subclass of Reader.
        Reader reader = new StringReader("123456789-987654321-ABCDE");

        int firstCharCode = reader.read();
        int secondCharCode = reader.read();

        System.out.println("First character: " + (char) firstCharCode);
        System.out.println("Second character: " + (char) secondCharCode);

        reader.skip(18); // Skips 18 characters.

        int code;
        while ((code = reader.read()) != -1) {
            System.out.println((char) code);
        }
        reader.close();
    }
}
Output:
First character: 1
Second character: 2
A
B
C
D
E

8. transferTo(Writer)

// Java 10+
public long transferTo(Writer out) throws IOException
Метод transferTo(Writer) используется для чтения всех символов из текущего Reader и записи их в указанный объект Writer, а также для возврата количества символов, переданных в Writer. После завершения текущий объект Reader будет находиться в конце stream. Этот метод не закроет текущий объект Reader или объект Writer.
Reader_transferTo_ex1.java
package org.o7planning.reader.ex;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;

public class Reader_transferTo_ex1 {

    public static void main(String[] args) throws IOException {
        // StringReader is a subclass of Reader.
        Reader reader = new StringReader("123456789-987654321-ABCDE");

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

        Writer writer = new FileWriter(file);

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

        reader.transferTo(writer);

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

9. markSupported()

public boolean markSupported()
Метод markSupported() используется для проверки того, поддерживает ли текущий объект Reader операцию mark(int). (См. также метод mark(int))
Reader
markSupported()?
StringReader
true
CharArrayReader
true
BufferedReader
true
LineNumberReader
true
FilterReader
true or false
InputStreamReader
false
FileReader
false
PushbackReader
false

10. mark(int)

public void mark(int readAheadLimit) throws IOException
Метод mark(int) позволяет отметить текущую позицию в stream. Вы можете продолжить чтение следующего символа и вызвать метод reset(), чтобы вернуться к ранее отмеченной позиции. При этом readAheadLimit - это максимальное количество символов, которые можно прочитать после маркировки без потери отмеченной позиции.
Примечание: Не все Reader поддерживают операцию mark(int). Чтобы быть уверенным, вам нужно вызвать метод markSupported(), чтобы проверить, поддерживает ли текущий объект Reader эту операцию.
Reader_mark_ex1.java
package org.o7planning.reader.ex;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

public class Reader_mark_ex1 {

    public static void main(String[] args) throws IOException {
        // StringReader is a subclass of Reader.
        Reader reader = new StringReader("123456789-987654321-ABCDE");

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

        System.out.println("StringReader markSupported? " + reader.markSupported()); // true
        
        reader.mark(9);
        
        int code1 = reader.read();
        int code2 = reader.read();
        
        System.out.println((char) code1); // '9'
        System.out.println((char) code2); // '8'
        reader.skip(5);
        
        System.out.println("Reset");
        reader.reset(); // Return to the marked position.
        
        int code;
        while((code = reader.read())!= -1) {
            System.out.println((char)code);
        }
        reader.close();
    }
}
Output:
StringReader markSupported? true
9
8
Reset
9
8
7
6
5
4
3
2
1
-
A
B
C
D
E

11. reset()

public void reset() throws IOException
Если этот объект Reader поддерживает маркировку текущей позиции с помощью метода mark(int), то для возврата в отмеченную позицию используется метод reset().

12. ready()

public boolean ready() throws IOException
Метод ready() возвращает true, если в stream есть символ, доступный для чтения без необходимости ждать, в противном случае он возвращает false.

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

Show More