当前位置: 首页 > 面试题库 >

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

韩景辉
2023-03-14
问题内容

我想将包含字符串的巨大文件拆分为一组新的(较小)文件,并尝试使用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方法之间的区别。在前一种情况下,如果未指定任何显式字符集,则使用系统的默认编码,而后者始终默认为。因此,我强烈建议您始终指定所需的字符集,即使它是或要记录您的意图,也可以避免在创建或的各种方法之间切换时感到意外。
InputStreamReader
OutputStreamWriterReader``Writer
FilesUTF-8``Charset.defaultCharset()``StandardCharsets.UTF_8``Reader``Writer

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

如果您愿意牺牲可移植性,则可以尝试一些优化。如果您知道字符集编码将明确映射'\n'(byte)'\n'大多数单html" target="_blank">字节编码的情况,并且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该操作所使用的方法。



 类似资料:
  • 问题内容: 我想像这将是一个简单的任务,但在以前的StackOverflow问题中我找不到我正在寻找的东西…… 我有一个专有格式的大文本文件,看起来像这样: 依此类推。 文本文件的大小从10kb到100mb不等。我需要用定界符分割此文件。如何基于块处理每个文件? 问题答案: 您可以使用itertools.groupby对列表中出现的行进行分组: 产量 或者,要处理组,您实际上不需要转换为列表:

  • 问题内容: 我有一个巨大的文本文件(〜1GB),可惜我使用的文本编辑器无法读取这么大的文件。但是,如果我可以将其分为两部分或三部分,那就没问题了,因此,作为练习,我想用python编写一个程序来做到这一点。 我想让程序执行的操作是找到文件的大小,将该数字分成多个部分,然后对于每个部分,逐块读取至该点,写入 文件名.nnn输出文件,然后读取- 到下一个换行符并将其写入,然后关闭输出文件,等等。显然,

  • 问题内容: 我有一个非常大的文本文件(45GB)。文本文件的每一行包含两个空格分隔的64位无符号整数,如下所示。 4624996948753406865 10214715013130414417 4305027007407867230 4569406367070518418 10817905656952544704 3697712211731468838 … … 我想读取文件并对数字进行一些操作。

  • 我正在制作一个应用程序,它处理存储在文本文件中的大量数据。本质上,应用程序浏览一个. txt文件,一旦找到,应用程序需要把文件中的所有数据放入JTable,然后我需要对数据执行一些过滤操作,然后将其导出。. txt文件中的数据格式如下: 有数千行。每行由双类型数字组成(A、B……均为1.3、2.0等) 我通过手动添加数组中的所有列名,然后将表的模型设置为 我已经把行作为'空'在这里,因为我不知道我

  • 本文向大家介绍python实现按行分割文件,包括了python实现按行分割文件的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python实现按行分割文件的具体代码,供大家参考,具体内容如下 小编再为大家分享一段代码: 将文本文件按照指定的行数分割成数个小的文本文件 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍js实现分割上传大文件,包括了js实现分割上传大文件的使用技巧和注意事项,需要的朋友参考一下 本文实例介绍了js上传文件操作,分享给大家供大家参考,具体内容如下 file.php: 1 运行: 2 选择2G文件测试: 3 完成并正常播放: 以上就是本文的全部内容,希望对大家的学习有所帮助。