Tags:

Tăng tốc độ đọc file với BufferedInputStream

BufferedInputStream cung cấp cơ chế đọc file theo từng khối và lưu nó trong bộ nhớ đệm. Nghĩa là BufferedInputStream sẽ đọc một khoảng dữ liệu lớn từ file và lưu nó vào bên trong bộ nhớ đệm, khi bạn đọc dữ liệu từ BufferedInputStream thì thật ra bạn đang đọc từ bộ nhớ đệm của nó, cho đến khi dữ liệu được trong bộ nhớ đệm được đọc hết thì BufferdInputStream mới tiếp tục đọc khối dữ liệu tiếp theo từ file và lưu vào bộ nhớ đệm cho đến khi đọc hết dữ liệu từ file. Việc này sẽ làm tăng tốc độ đọc dữ liệu từ file hơn so với việc bạn đọc từng byte từ file ra. 

Ví dụ đọc file với BufferedInputStream

Ví dụ 1: Tổng quan các method trong BufferedInputStream

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.Period;

// Java program to demonstrate BufferedInputStream methods 
class BufferedInputStreamDemo {
    public static void main(String args[]) throws IOException {
        // attach the file to FileInputStream 
        BufferedInputStream bin = null;
        try {
            FileInputStream fin = new FileInputStream("file1.txt");

            bin = new BufferedInputStream(fin);

            // illustrating available method 
            System.out.println("Number of remaining bytes:" +
                    bin.available());

            // illustrating markSupported() and mark() method 
            boolean b = bin.markSupported();
            if (b)
                bin.mark(bin.available());

            // illustrating skip method 
            /*Original File content:
             * This is my first line
             * This is my second line*/
            bin.skip(4);
            System.out.println("FileContents :");

            // read characters from FileInputStream and 
            // write them 
            int ch;
            while ((ch = bin.read()) != -1)
                System.out.print((char) ch);

            // illustrating reset() method 
            bin.reset();
            while ((ch = bin.read()) != -1)
                System.out.print((char) ch);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

Output

Number of remaining bytes:47

FileContents : is my first line

This is my second line

This is my first line

This is my second line

Ví dụ 2: Đọc từng ký tự file text trong BufferedInputStream

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

class BufferedInputStreamDemo {
    public static void main(String args[]) {
        BufferedInputStream bin = null;
        try {
        FileInputStream fin = new FileInputStream("/Users/nguyenthanhhai/Desktop/test.txt");

        bin = new BufferedInputStream(fin);
        int ch;
        while ((ch = bin.read()) != -1)
            System.out.print((char) ch);

            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

BufferedInputStream thường được dùng để bọc các InputStream khác để tăng tốc độ đọc dữ liệu.BuferedInputStream sẽ khởi tạo một mảng byte và đọc một khối dữ liệu bằng cách gọi method InputStream.read(byte[]). Các dữ liệu bạn đọc từ BufferedInputStream sẽ được đọc từ mảng byte này ra chứ không phải đọc trực tiếp từ file.

Bạn cũng có thể custom kích thước của mảng byte bên trong BufferedInputStream như sau

int bufferSize = 8 * 1024;
    
BufferedInputStream bufferedInputStream = new BufferedInputStream(
                      new FileInputStream("c:\\data\\input-file.txt"),
                      bufferSize
    );

Tối ưu hiệu suất với BufferedInputStream

Chúng ta nên làm một vài thí nghiệm với các kích thước của mảng byte bên trong BufferedInputStream để xem đâu là kích thước tối ưu cho mảng đệm. Kích thước của mảng đệm để tối ưu phụ thuộc vào phần cứng và network.

Ví dụ nếu ổ điã cứng luôn đọc dữ liệu với kích thước nhỏ nhất là 4kb thì thật là ngáo nếu kích thước bộ đệm nhỏ hơn 4Kb phải không nào. Chúng ta cần một mảng đệm có kích thước lớn hơn hoặc bằng 4Kb phải không nào? Cho nên chúng ta cần tìm hiểu xem ổ cứng của chúng ta đọc mỗi lần là bao nhiêu byte và đây rất có thể là kích thước tối ưu nhất cho bạn. 

Đóng BufferedInputStream

Để đóng kết nối của BufferedInputStream sử dụng close() method. close() method sẽ giúp ngắt kết nối dữ BufferedInputStream các tài liệu mà nó tham chiếu đến.

try(BufferedInputStream bufferedInputStream =
        new BufferedInputStream( new FileInputStream("c:\\data\\input-file.txt") ) ) {

    int data = bufferedInputStream.read();
    while(data != -1){
        data = bufferedInputStream.read();
    }
}

Số byte còn lại trong BufferedInputStream

Sử dụng available() method để kiểm tra xem còn bao nhiêu byte sẽ được đọc nữa trong input stream/

int bytes = bufferedInputStream.available();

Skip byte trong BufferedInputStream

Sử dụng skip() method để nhảy qua n byte nếu bạn không muốn đọc chúng vào kết quả vì nhiều lý do khác nhau như chúng là các byte rác etc. skip() sẽ về số byte thật sự được nhảy qua. 

long bytes = bufferedInputStream.skip(1);

Kết

So với việc sử dụng FileInputStream để đọc file thì chúng ta nên sử dụng thêm BufferedInputStream bao bên ngoài FileInputStream sẽ giúp tăng tốc độ đọc file hơn vì cơ chế sử dụng bộ nhớ đệm và đọc file theo từng khối của nó.

Nguồn tham khảo

http://tutorials.jenkov.com/java-io/bufferedinputstream.html

https://www.geeksforgeeks.org/java-io-bufferedinputstream-class-java/

 

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