betacode

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

  1. FileReader
  2. Examples
  3. Проблемы UTF-8 BOM!

1. FileReader

FileReader - это подкласс InputStreamReader, который используется для чтения текстовых файлов.
FileReader имеет только методы, унаследованные от InputStreamReader. На самом деле вы можете использоватьInputStreamReader для чтения символов из любого источника, однако FileReader специально разработан для чтения символов из файловой системы.
FileReader​ constructors
FileReader​(File file)    

FileReader​(FileDescriptor fd)    

FileReader​(File file, Charset charset)    

FileReader​(String fileName)    

FileReader​(String fileName, Charset charset)
Примечание: Конструкторы с параметром Charset были добавлены в FileReader, начиная с версией Java 11. Поэтому, если вы используете более раннюю версию Java и хотите прочитать файл с указанной кодировкой, вместо этого используйте класс InputStreamReader.

2. Examples

Например, чтение текстового файла:
file-test.txt
File Content
FileReaderEx1.java
package org.o7planning.filereader.ex;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;

public class FileReaderEx1 {

    public static void main(String[] args) throws MalformedURLException, IOException {
        File file = new File("file-test.txt");
 
        FileReader fis = new FileReader(file);
        
        int charCode;
        while((charCode = fis.read()) != -1) {
            System.out.println((char)charCode + "  " + charCode);
        }
        fis.close();
    }
}
Output:
F  70
i  105
l  108
e  101
   32
C  67
o  111
n  110
t  116
e  101
n  110
t  116
При чтении текстового файла лучше использовать комбинацию BufferedReader и FileReader для достижения лучшей производительности:
students.txt
# Students:

John P
Sarah M
# Sarah B
Charles B
Mary T
Sophia B
FileReaderEx2.java
package org.o7planning.filereader.ex;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;

public class FileReaderEx2 {

    public static void main(String[] args) throws MalformedURLException, IOException {
        File file = new File("students.txt");
 
        Reader reader = new FileReader(file);
        BufferedReader br = new BufferedReader(reader);
        
        String line;
        while((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
}
Output:
# Students:

John P
Sarah M
# Sarah B
Charles B
Mary T
Sophia B
Например: Чтение текстового файла и печать строк текста, которые не начинаются с символа "#" (строка комментария):
FileReaderEx3.java
package org.o7planning.filereader.ex;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.MalformedURLException;

public class FileReaderEx3 {

    public static void main(String[] args) throws MalformedURLException, IOException {
        File file = new File("students.txt");
 
        Reader reader = new FileReader(file);
        BufferedReader br = new BufferedReader(reader);
        
        br.lines() // java.util.stream.Stream
           .filter(line -> !line.startsWith("#")) // Not starts with "#".
           .forEach(System.out::println);
        
        br.close();
    }
}
Output:
John P
Sarah M
Charles B
Mary T
Sophia B

3. Проблемы UTF-8 BOM!

До того, как UTF-8 стал популярным, генераторы файлов UTF-8 всегда добавляли первые 3 bytes, чтобы отметить, что этот файл был закодирован UTF-8, они часто называются BOM (Byte Order Mark). В то время как файлы UTF-8, созданные Java, не включают BOM.
FileReader не удаляет автоматически BOM при чтении файлов UTF-8. Команда разработчиков Java понимает это, однако никаких обновлений не будет, так как это нарушит предыдущие сторонние библиотеки на базе Java, такие как XML Parser и т.д.
Например, ниже приведен файл UTF-8 (BOM), созданный старым инструментом, вы можете скачать его для проверки обсуждаемой проблемы:
utf8-file-with-bom-test.txt
Hello
Используйте FileReader для чтения вышеуказанного файла:
FileReader_Utf8_BOM.java
package org.o7planning.filereader.ex;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;

public class FileReader_Utf8_BOM {

    public static void main(String[] args) throws MalformedURLException, IOException {
        File file = new File("utf8-file-with-bom-test.txt");  
        
        System.out.println("--- Read by FileReader ---");
        readByFileReader(file);
        
        System.out.println("--- Read by InputStreamReader ---");
        readByInputStreamReader(file);
    }

    private static void readByFileReader(File file) throws IOException {
        FileReader fr = new FileReader(file, StandardCharsets.UTF_8);

        int charCode;
        while ((charCode = fr.read()) != -1) {
            System.out.println((char) charCode + "  " + charCode);
        }
        fr.close();
    }
    
    private static void readByInputStreamReader(File file) throws IOException {
        InputStream is = new FileInputStream(file);

        InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);

        int charCode;
        while ((charCode = isr.read()) != -1) {
            System.out.println((char) charCode + "  " + charCode);
        }
        isr.close();
    }
}
Output:
--- Read by FileReader ---
  65279
H  72
e  101
l  108
l  108
o  111
--- Read by InputStreamReader ---
  65279
H  72
e  101
l  108
l  108
o  111
В результате появляется символ с кодом 65279, который является нежелательным символом.
Некоторые из следующих классов поддерживают исключение BOM, которое вы можете использовать:
BOMInputStream
BOMInputStream - это класс в библиотеке Apache Commons IO, который поддерживает удаление BOM.
Maven dependency
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>
BOMInputStreamEx1.java
package org.o7planning.filereader.ex;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

import org.apache.commons.io.input.BOMInputStream;

public class BOMInputStreamEx1 {

    public static void main(String[] args) throws IOException {
        File file = new File("utf8-file-with-bom-test.txt");
        FileInputStream fis = new FileInputStream(file);

        BOMInputStream bis = new BOMInputStream(fis);

        InputStreamReader isr = new InputStreamReader(bis, StandardCharsets.UTF_8);

        int charCode;
        while ((charCode = isr.read()) != -1) {
            System.out.println((char) charCode + "  " + charCode);
        }
        isr.close();
    }
}
Output:
H  72
e  101
l  108
l  108
o  111
UnicodeReader
UnicodeReader - это класс в библиотеке "Google Data Java Client Library", который поддерживает удаление BOM.
Maven dependency
<!-- https://mvnrepository.com/artifact/com.google.gdata/core -->
<dependency>
    <groupId>com.google.gdata</groupId>
    <artifactId>core</artifactId>
    <version>1.47.1</version>
</dependency>
UnicodeReaderEx1.java
package org.o7planning.filereader.ex;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.google.gdata.util.io.base.UnicodeReader;

public class UnicodeReaderEx1 {

    public static void main(String[] args) throws IOException {
        File file = new File("utf8-file-with-bom-test.txt");
        FileInputStream fis = new FileInputStream(file);
        
        UnicodeReader isr = new UnicodeReader(fis, "UTF-8");

        int charCode;
        while ((charCode = isr.read()) != -1) {
            System.out.println((char) charCode + "  " + charCode);
        }
        isr.close();
    }  
}
Output:
H  72
e  101
l  108
l  108
o  111

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

Show More