Tags:

Tối ưu hoá tốc độ đọc file text với BufferedReader

BufferedReader sẽ rất có ích nếu chúng ta muốn đọc nội dung văn bản từ các nguồn như file, socket, network etc.

BufferedReader cho phép chúng ta giảm thiểu số lượng thao tác I/O bằng cách đọc một khối ký tự và lưu chúng vào bộ nhớ đệm(bộ nhớ đệm là một mảng ký tự có kích thước mặc định là 8192). Như vậy chúng ta sẽ đọc dữ liệu từ bộ đệm nếu nó còn dữ liệu thay vì phải đọc từ luồng dữ liệu bên dưới. Khi bộ nhớ đệm đã được đọc hết nó sẽ tự động đọc một khối dữ liệu khác vào cứ như vậy cho đến khi hết dữ liệu ở luồng bên dưới.

Khởi tạo BufferedReader

BufferedReader là một clas bọc bên ngoài FileReader để tạo cơ chế sử dụng bộ nhớ đệm cho FileReader.

BufferedReader reader = 
  new BufferedReader(new FileReader("/Users/nguyenthanhhai/Desktop/test.txt"));

Mặc định kích thước của bộ nhớ đệm là 8192, chúng ta có thể custom lại như sau

int bufferSize = 8 * 1024;

BufferedReader reader = 
  new BufferedReader(new FileReader("/Users/nguyenthanhhai/Desktop/test.txt"), bufferSize);

Đọc từng dòng trong BufferedReader

readLine() trả về một String tương ứng với một dòng trong BufferedReader.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class BufferedReaderExample {

    public static void main(String[] args) {
        try (BufferedReader bufferedReader =
                     new BufferedReader(new FileReader("/Users/nguyenthanhhai/Desktop/test.txt"))) {

            String line = bufferedReader.readLine();
            while (line != null)

            {
                System.out.println(line);
                line = bufferedReader.readLine();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Đọc từng ký tự trong BufferedReader

read() trả về từng ký tự trong BufferedReader hoặc trả về -1 nếu đã đọc đến cuối BufferedReader.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class BufferedReaderExample {

    public static void main(String[] args) {
        try (BufferedReader bufferedReader =
                     new BufferedReader(new FileReader("/Users/nguyenthanhhai/Desktop/test.txt"))) {

            int data = bufferedReader.read();
            while (data != -1) {
                System.out.print((char) data);
                data = bufferedReader.read();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Đọc nhiều ký tự một lúc trong BufferedReader

Sử dụng read(char[] buf, int off, int len) để đọc một mảng ký tự vàobuf, bắt đầu tại off và tối đa len ký tự.read(char[] buf, int off, int len) trả về số byte đọc được hoặc -1 nếu đọc đến cuối BufferedReader.

public String readMultipleChars(BufferedReader reader) throws IOException {
    int length = 100;
    char[] chars = new char[length];
    int charsRead = reader.read(chars, 0, length);
 
    String result;
    if (charsRead != -1) {
        result = new String(chars, 0, charsRead);
    } else {
        result = "";
    }
 
    return result;
}

Loại bỏ các ký tự trong BufferedReader

Đôi lúc chúng ta cần loại bỏ các ký tự trong BufferedReader vì các ký do khác nhau, sử dụng skip() method để xử lý trong trường hợp này. skip() trả về số ký tự thật sự đã bị bỏ qua.

long charsSkipped = bufferedReader.skip(24);

Đóng kết nối BufferedReader

Bắt buộc chúng ta phải đóng kết nối đến các tài nguyên mà BufferedReader đang kết nối đến. Gọi close() method sau khi đã hoàn tất mọi thao tác.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class BufferedReaderExample {

    public static void main(String[] args) {
        try (FileReader fileReader = new FileReader("/Users/nguyenthanhhai/Desktop/test.txt");
             BufferedReader bufferedReader = new BufferedReader(fileReader)) {

            int data = bufferedReader.read();
            while (data != -1) {
                System.out.print((char) data);
                data = bufferedReader.read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Note: Chúng ta không cần gọi close() cho FileReader vì bên close() method của BufferedReader đã thực hiện cho chúng ta.

mark và reset

Chúng ta có thể sử dụng mark(int readAheadLimit) reset() method để giới hạn đọc từng readAheadLimit ký tự cho đến khi gọi reset() được gọi thì BufferedReader sẽ đọc nhiều byte nhất có thể vào bộ nhớ đệm.

Ví dụ sử dụng mark() reset() để loại bỏ các khoảng trắng ở đầu file.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

class BufferedReaderExample {

    public static void main(String[] args) throws IOException {
        try (BufferedReader reader =
                     new BufferedReader(new StringReader("    Lorem ipsum dolor sit amet."))) {
            do {
                reader.mark(1);
            } while (Character.isWhitespace(reader.read()));

            reader.reset();
            String result = reader.readLine();
            System.out.println(result);
        }

    }
}

Output: “Lorem ipsum dolor sit amet.”

Tóm lược

BufferedReader trong đa số các trường hợp nên được sử dụng với FileReader để tăng tốc độ đọc file. Ngoài ra BufferedReader còn nhiều method hữu ích như readLine() để đọc từng dòng, readLine() thường được sử dụng rất nhiều trong vì thông thường mỗi dòng trong file text là một bản mô tả đầy đủ của một cấu trúc.

Ví dụ file eng-vi.txt sử dụng trong ứng dụng từ điển

happy - adj - Hạnh phúc
sad - adj - Buồn
year - n - Năm

Nguồn tham khảo

https://www.baeldung.com/java-buffered-reader#2-reading-line-by-line

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x