[ JAVA ] 分块读取文本文件

2,035 阅读1分钟

代码如下:

package com.github.jwenjian.util.io;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;

/**
 * A chunked reader for text file
 *
 * Should use the instance of this class in try-with-resource block or call instance.close() in finally block
 *
 * @author jwenjian
 */
public class TextFileChunkedReader implements AutoCloseable {
    private final int chunkSize;
    private final File file;
    private Charset charset;
    private BufferedReader br;

    /**
     * Create a new reader instance
     *
     * @param chunkSize chunk size, cannot be negative
     * @param file      file to read, cannot be null
     */
    public TextFileChunkedReader(int chunkSize, File file) {
        this.chunkSize = chunkSize;
        this.file = file;
        this.charset = Charset.defaultCharset();
        validateInput();
    }

    /**
     * Create a new reader instance
     *
     * @param chunkSize chunk size, cannot be negative
     * @param file      file to read, cannot be null
     * @param charset   charset used to read file, cannot be null
     */
    public TextFileChunkedReader(int chunkSize, File file, Charset charset) {
        this.chunkSize = chunkSize;
        this.file = file;
        this.charset = charset;
        validateInput();
    }

    private void validateInput() {
        if (this.chunkSize <= 0) {
            throw new IllegalArgumentException("chunkCount cannot be negative");
        }
        if (this.file == null || !this.file.exists() || this.file.isDirectory()) {
            throw new IllegalArgumentException("file is null or not exists or is a directory");
        }
        if (this.charset == null) {
            throw new IllegalArgumentException("charset cannot be null");
        }
    }

    /**
     * Read next chunk from the file
     *
     * @return A collection of strings from the file which contains {chunkSize} strings in maximum, or empty list if reaches the End Of File
     * @throws IOException When failed to read file
     */
    public Collection<String> readNextChunk() throws IOException {
        if (this.br == null) {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset));
        }
        Collection<String> result = new ArrayList<>(chunkSize);
        String line;
        int count = 0;
        while ((line = br.readLine()) != null) {
            result.add(line);
            count++;
            if (count >= chunkSize) {
                break;
            }
        }
        return result;
    }

    /**
     * Close the resources relates to the file
     *
     * @throws Exception When failed to close the resources
     */
    @Override
    public void close() throws Exception {
        if (br != null) {
            br.close();
        }
    }

    public int getChunkSize() {
        return chunkSize;
    }

    public File getFile() {
        return file;
    }

    public Charset getCharset() {
        return charset;
    }
}

使用示例:

public static void main(String[] args) {
        File file = new File("cities.csv");
        int chunkSize = 100;
        Collection<String> lines = new ArrayList<>();
        try (TextFileChunkedReader tfcr = new TextFileChunkedReader(chunkSize, file)) {
            while (!(lines = tfcr.readNextChunk()).isEmpty()) {
                // handle lines which includes 100 strings in maximum
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

注意:非线程安全,不可在线程间共享