openplanning

Hướng dẫn và ví dụ Java FileReader

Xem thêm các chuyên mục:

Nhóm phát triển của chúng tôi vừa ra mắt website langlearning.net học tiếng Anh, Nga, Đức, Pháp, Việt, Trung, Hàn, Nhật, ... miễn phí cho tất cả mọi người.
Là một website được viết trên công nghệ web Flutter vì vậy hỗ trợ rất tốt cho người học, kể cả những người học khó tính nhất.
Hiện tại website đang tiếp tục được cập nhập nội dung cho phong phú và đầy đủ hơn. Mong các bạn nghé thăm và ủng hộ website mới của chúng tôi.
Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook

1- FileReader

FileReader là một lớp con của InputStreamReader, nó được sử dụng để đọc các file văn bản.
FileReader không có thêm các phương thức nào ngoài các phương thức được thừa kế từ InputStreamReader, thực tế bạn có thể sử dụng InputStreamReader để đọc các ký tự từ bất kỳ một nguồn nào, tuy nhiên FileReader được thiết kế riêng để đọc các ký tự từ file hệ thống.
FileReader​ constructors

FileReader​(File file)    

FileReader​(FileDescriptor fd)    

FileReader​(File file, Charset charset)    

FileReader​(String fileName)    

FileReader​(String fileName, Charset charset)
Chú ý: Các constructor có tham số Charset được thêm vào FileReader từ phiên bản Java 11, vì vậy nếu bạn đang sử dụng Java phiên bản cũ hơn và muốn đọc một file với mã hoá (encoding) được chỉ định hãy sử dụng lớp InputStreamReader để thay thế.

2- Examples

Ví dụ đọc một file văn bản:
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
Khi đọc một file văn bản bạn nên sử dụng kết hợp BufferedReaderFileReader để có được hiệu xuất tốt nhất:
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
Ví dụ: Đọc một file văn bản và in ra các dòng văn bản không bắt đầu bởi ký tự '#' (Dòng chú thích):
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- Vấn đề UTF-8 BOM!

Trước khi UTF-8 trở lên phổ biến các công cụ tạo ra file UTF-8 luôn thêm vào 3 bytes đầu tiên để đánh dấu rằng đây là file được mã hoá UTF-8, chúng thường được gọi là BOM (Byte Order Mark). Trong khi các file UTF-8 được tạo ra bởi Java không bao gồm BOM.
FileReader không tự động loại bỏ BOM khi đọc các file UTF-8. Đội ngũ thiết kế Java hiểu được điều này tuy nhiên không có một bản cập nhập nào được thực hiện vì nó sẽ phá vỡ các thư viện của bên thứ ba viết trên Java trước đó như XML Parser, ...
Chẳng hạn, dưới đây là một file UTF-8 (BOM) được tạo bởi một công cụ cũ, bạn có thể download nó để test vấn đề đang được thảo luận:
utf8-file-with-bom-test.txt

Hello
Và sử dụng FileReader để đọc file nói trên:
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
Ký tự với mã 65279 xuất hiện trong kết quả, nó là một ký tự không mong muốn.
Một vài lớp dưới đây hỗ trợ loại bỏ BOM bạn có thể cân nhắc sử dụng:
BOMInputStream
BOMInputStream là một lớp trong thư viện Apache Commons IO hỗ trợ loại bỏ 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 là một lớp nằm trong thư viện "Google Data Java Client Library" hỗ trợ loại bỏ 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

Xem thêm các chuyên mục: