读取大文件(例如非常大的文本文档)的最佳方式

问题描述 投票:0回答:5

我是java新手...在我当前的项目中,我需要读取和写入一个非常大的文本文件(1 GB - 5 GB)...首先我使用了此类:BufferedReaderBufferedWriter

public static String read(String dir) {
    BufferedReader br;
    String result = "", line;
    try {
        br = new BufferedReader(new InputStreamReader(new FileInputStream(dir), "UTF-8"));
        while ((line = br.readLine()) != null) {
            result += line + "\n";
        }
    } catch (IOException ex) {
        //do something
    }
    return result;
}

public static void write(String dir, String text) {
    BufferedWriter bw;
    try {
        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dir), "UTF-8"));
        bw.write("");
        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) != '\n') {
                bw.append(text.charAt(i));
            } else {
                bw.newLine();
            }
        }
        bw.flush();
    } catch (IOException ex) {
        //do something
    }
}

这个类效果很好,但不适用于大文件......

然后我使用 MappedByteBuffer 作为

read()
方法(我不知道如何使用此类编写文件):

public static String read(String dir) {
    FileChannel fc;
    String s = "";
    try {
        fc = new RandomAccessFile(dir, "r").getChannel();
        MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
        buffer.load();
        buffer.force();
        for (int i = 0; i < buffer.limit(); i++) {
            s += (char) buffer.get();
        } //I know the problem is here
        buffer.clear();
        inChannel.close();
    } catch (IOException e) {
        //do something
    }
    return s;
}

但仍然无法读取大文件(超过 30-40 MB),即使记事本也比我的应用程序更快:))

另一个问题是我不知道如何以第二种方式更改编码(例如“UTF-8”,“ANSI”,...)

所以各位,请告诉我哪种是读写 laaaarge 文件的最佳方法? 有什么想法吗?

java bufferedreader bytebuffer mappedbytebuffer
5个回答
2
投票
result += line + "\n";

此行尝试将整个文件内容保留在内存中。尝试像这样阅读时处理每一行

while ((line = br.readLine()) != null) {
            processLine( line ); // this may write it to another file.
        }

1
投票

至少我建议改变

result += line + "\n";

到 StringBuilder。

resultBldr.append(line).append("\n");

这可以避免在每一行上创建一个新的字符串对象——一个越来越大、越来越大的字符串对象。

此外,您绝对应该将输出写入文件逐行。不要累积所有文本然后然后输出它。

换句话说,在这种情况下,不建议将

read
write
功能完全分离。


0
投票

认为字符串的每个连接都会创建一个新字符串,因此,如果您读取 40 MB 大文件的每个字符并连接,您总共会创建 40.000.000 个字符串,就像

read()
中的 40.000.000 个字符串。

尝试使用

StringBuffer
而不是
String
,在这种情况下推荐使用。


0
投票

一次性读取 1GB - 5GB 范围内的大文件总是一个坏主意。将会有巨大的性能开销,并且您的应用程序将会变慢。

最好将这个大文件分成较小的块,然后逐块读取。我认为如果您开始以较小的块读取文件,您编写的代码将完美运行。

您是否听说过 HDFS 系统、Solr 索引、apache hadoop 框架,它们是专门为操作大数据而提供的。你可能想看看。


0
投票

最好使用 Scanner 类,因为它使用流,并尝试将内容推送到数据库中,因为数据库可以存储更多数据,以便您可以使用数据执行任何操作。要读取数据,请使用具有 FETCH 限制的查询。我用它来处理 3 GB 文件,它工作正常,没有任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.