gpt4 book ai didi

java - 从巨大的文本文件中选择随机行

转载 作者:行者123 更新时间:2023-11-30 02:23:56 25 4
gpt4 key购买 nike

我有一个非常大的文本文件 18000000 行 4Gbyte,我想从中挑选一些随机行,我编写了以下代码来执行此操作,但速度很慢

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {

public static void main(String[] args) throws IOException {
int sampleSize =3000;
int fileSize = 18000000;
int[] linesNumber = new int[sampleSize];
Random r = new Random();
for (int i = 0; i < linesNumber.length; i++) {
linesNumber[i] = r.nextInt(fileSize);

}
List<Integer> list = Arrays.stream(linesNumber).boxed().collect(Collectors.toList());
Collections.sort(list);

BufferedWriter outputWriter = Files.newBufferedWriter(Paths.get("output.txt"));

for (int i : list) {

try (Stream<String> lines = Files.lines(Paths.get("huge_text_file"))) {
String en=enlines.skip(i-1).findFirst().get();

outputWriter.write(en+"\n");
lines.close();

} catch (Exception e) {
System.err.println(e);

}

}
outputWriter.close();


}
}

有没有更优雅更快的方法来做到这一点?谢谢。

最佳答案

我发现您当前的代码有一些问题。

  1. 您当前正在将整个文件加载到 RAM 中。我对您的示例文件了解不多,但我使用的那个文件使我的默认 JVM 崩溃了。
  2. 你一遍又一遍地跳过相同的行,对于前面的行更是如此 - 这是非常低效的,就像 O(n^n) 之类的。如果您可以用这种方法处理 500MB 的文件,我会感到惊讶。

这是我想到的:

public static void main(String[] args) throws IOException {
int sampleSize = 3000;
int fileSize = 50000;
int[] linesNumber = new int[sampleSize];
Random r = new Random();
for (int i = 0; i < linesNumber.length; i++) {
linesNumber[i] = r.nextInt(fileSize);

}
List<Integer> list = Arrays.stream(linesNumber).boxed().collect(Collectors.toList());
Collections.sort(list);

BufferedWriter outputWriter = Files.newBufferedWriter(Paths.get("localOutput/output.txt"));
long t1 = System.currentTimeMillis();
try(BufferedReader reader = new BufferedReader(new FileReader("extremely large file.txt")))
{
int index = 0;//keep track of what item we're on in the list
int currentIndex = 0;//keep track of what line we're on in the input file
while(index < sampleSize)//while we still haven't finished the list
{
if(currentIndex == list.get(index))//if we reach a line
{
outputWriter.write(reader.readLine());
outputWriter.write("\n");//readLine doesn't include the newline characters
while(index < sampleSize && list.get(index) <= currentIndex)//have to put this here in case of duplicates in the list
index++;
}
else
reader.readLine();//readLine is dang fast. There may be faster ways to skip a line, but this is still plenty fast.
currentIndex++;
}
} catch (Exception e) {
System.err.println(e);
}
outputWriter.close();
System.out.println(String.format("Took %d milliseconds", System.currentTimeMillis() - t1));
}

在样本大小为 30、文件大小为 50000 的 4.7GB 文件上运行时,这大约需要 87 毫秒;当我将样本大小更改为 3000 时,大约需要 91 毫秒。当我将文件大小增加到10,000。 Tl;Dr 对于本段 = 它的扩展性非常好,并且随着样本量的增大,它的扩展性也非常好。

直接回答你的问题“有没有更优雅更快的方法来做到这一点?”就在这里。 更快的方法是自己跳过行,不要将整个文件加载到内存中,并确保继续使用缓冲的读取器和写入器。此外,我会避免尝试执行您的操作拥有原始数组缓冲区或类似的东西 - 只是不要。

如果您想了解更多它的工作原理,请随意逐步完成我提供的方法。

关于java - 从巨大的文本文件中选择随机行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46124875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com