按最大行分割非常大的文本文件

nimo23:

我想将包含字符串的大文件拆分为一组新的(较小的)文件,并尝试使用nio2。

我不想将整个文件加载到内存中,因此我尝试了BufferedReader。

较小的文本文件应受文本行数的限制。

该解决方案有效,但是我想问一问,有人知道使用usion java 8(也许是带有stream()-api的lamdas)和nio2具有更好性能的解决方案:

public void splitTextFiles(Path bigFile, int maxRows) throws IOException{

        int i = 1;
        try(BufferedReader reader = Files.newBufferedReader(bigFile)){
            String line = null;
            int lineNum = 1;

            Path splitFile = Paths.get(i + "split.txt");
            BufferedWriter writer = Files.newBufferedWriter(splitFile, StandardOpenOption.CREATE);

            while ((line = reader.readLine()) != null) {

                if(lineNum > maxRows){
                    writer.close();
                    lineNum = 1;
                    i++;
                    splitFile = Paths.get(i + "split.txt");
                    writer = Files.newBufferedWriter(splitFile, StandardOpenOption.CREATE);
                }

                writer.append(line);
                writer.newLine();
                lineNum++;
            }

            writer.close();
        }
}
霍尔格:

当心直接使用/ 及其子类和/的/ factory方法之间的区别在前一种情况下,如果未指定任何显式字符集,则使用系统的默认编码,而后者始终默认为因此,我强烈建议您始终指定所需的字符集,即使它是要记录您的意图,也可以避免在创建的各种方法之间切换时感到意外 InputStreamReaderOutputStreamWriterReaderWriter FilesUTF-8Charset.defaultCharset()StandardCharsets.UTF_8ReaderWriter


如果要在行边界处分割,则无法解决文件内容的问题。因此,您无法像合并时那样优化它

如果您愿意牺牲可移植性,则可以尝试一些优化。如果您知道charset编码将明确映射'\n'(byte)'\n'大多数单字节编码的情况,并且UTF-8您可以扫描字节级别的换行符以获取拆分的文件位置,并避免从应用程序传输任何数据到I / O系统。

public void splitTextFiles(Path bigFile, int maxRows) throws IOException {
    MappedByteBuffer bb;
    try(FileChannel in = FileChannel.open(bigFile, READ)) {
        bb=in.map(FileChannel.MapMode.READ_ONLY, 0, in.size());
    }
    for(int start=0, pos=0, end=bb.remaining(), i=1, lineNum=1; pos<end; lineNum++) {
        while(pos<end && bb.get(pos++)!='\n');
        if(lineNum < maxRows && pos<end) continue;
        Path splitFile = Paths.get(i++ + "split.txt");
        // if you want to overwrite existing files use CREATE, TRUNCATE_EXISTING
        try(FileChannel out = FileChannel.open(splitFile, CREATE_NEW, WRITE)) {
            bb.position(start).limit(pos);
            while(bb.hasRemaining()) out.write(bb);
            bb.clear();
            start=pos;
            lineNum = 0;
        }
    }
}

缺点是它不适用于UTF-16or或EBCDICand之类的编码BufferedReader.readLine()与之不同的是,它不像'\r'旧MacOS9中那样支持单独作为行终止符。

此外,它仅支持小于2GB的文件。由于虚拟地址空间有限,该限制在32Bit JVM上甚至可能更小。对于大于限制的文件,有必要遍历源文件的各个块,map然后逐个进行迭代

这些问题可以解决,但会增加此方法的复杂性。考虑到速度在我的机器上仅提高了约15%(我并没有期望更多,因为I / O在这里占主导地位),并且在复杂性提高时甚至会更小,我认为这是不值得的。


最重要的是,对于此任务,Reader/ Writer方法已足够,但您应注意Charset该操作使用的方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在非常大的文本文件(〜150 GB)中找到最大的数字?

如何处理非常大的文本文件?

在Java中读取非常大的文本文件

使用Python解析非常大的文本文件?

随机分配非常大的文本文件的行

在HDFS中将多个文本文件串联为一个非常大的文件

C#从SQL查询建立非常大的文本文件

在PowerShell中对非常大的文本文件进行排序

编辑非常大的SQL转储/文本文件(在Linux上)

在C ++中有效读取非常大的文本文件

在C#中读取和写入非常大的文本文件

读取非常大的一个班轮文本文件

使用Powershell从非常大的文本文件中获得子字符串

在python中批处理非常大的文本文件

我需要拆分一个非常大的文本文件

有效地删除一个非常大的文本文件的最后两行

如何通过VBA优化从excel中非常大的文本文件中提取数据的性能

如何分割非常大的python文件?

读取大文本文件非常慢

无论如何,我可以加快将非常大的文本文件数据添加到AutoComplete ComboBox的速度吗?

如何在Powershell中以预定义的字符串拆分非常大的文本文件(4GB),并快速完成

如何在Windows中分割大文本文件?

分割大文本文件时控制输出

如何使用 kate 将文本文件编辑为最大行长

如何将大文本文件分割成行数相等的小文件?

python分割文本文件功能

不阅读就分割文本文件

从文本文件分割数据

大文本文件中的词频