【问题标题】:Fastest way for data look up from a .txt file which contains 11million+ lines of info从包含 1100 万多行信息的 .txt 文件中查找数据的最快方式
【发布时间】:2016-01-12 05:38:32
【问题描述】:

所以我一直在尝试解决这个问题,但无法找到“快速”的解决方案。我确实有一个解决方案,但实际上需要 3 天才能完成,但不幸的是这太长了。

  • 我想做什么:

所以我有一个包含唯一时间戳的文本文件(称为 1.txt),并有一个包含混合数据的辅助文本文件(称为 2.txt),目的是读取第一个时间戳从 1.txt 并在 2.txt 中找到匹配项并将其输出到新文件中,并不断执行此操作。 1.txt 中有大约 100,000 个时间戳,2.txt 中有超过 1100 万行。

  • 我所取得的成就:

到目前为止,我得到的是它获得了第一个时间戳,并有一个嵌套循环,通过它循环遍历 1100 万行以找到匹配项。一旦找到匹配项,它将把它存储在一个变量中,直到它移动到下一个时间戳,在那里它写出该数据。解决方法如下:

public class fedOrganiser5 {
    private static String directory = "C:\\Users\\xxx\\Desktop\\Files\\";
    private static String file = "combined.txt";
    private static Integer fileNo = 1;

    public static void main(String[] args) throws IOException {
        String sCurrentLine = "";
        int i = 1;
        String mapperValue = "";
        String outputFirst = "";
        String outputSecond = "";
        String outputThird = "";
        long timer;
        int counter = 0;
        int test = 0;
        timer = System.currentTimeMillis();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(directory + "newfile" + fileNo + ".txt"));
            BufferedWriter writer = new BufferedWriter(new FileWriter(directory + "final_" + fileNo + ".txt"));
            BufferedReader mapper = new BufferedReader(new FileReader(directory + file));
            for (sCurrentLine = reader.readLine(); sCurrentLine != null; sCurrentLine = reader.readLine()) {
                if (!sCurrentLine.trim().isEmpty() && sCurrentLine.trim().length() > 2) {
                    sCurrentLine = sCurrentLine.replace(" ", "").replace(", ", "").replace(",", "").replace("[", "");
                    try {
                        if (counter>0) {
                            writer.write(outputFirst + outputSecond + outputThird);
                            outputFirst = "";
                            outputSecond = "";
                            outputThird = "";
                            counter = 0;
                            test=0;
                            i++;
                            mapper.close();
                            mapper = new BufferedReader(new FileReader(directory + file));                      
                            System.out.println("Writing out details for " + sCurrentLine);
                        }
                        for (mapperValue = mapper.readLine(); mapperValue != null; mapperValue = mapper.readLine()) {
                            test++;
                            System.out.println("Find match " + i + " - " + test);
                            if (mapperValue.contains(sCurrentLine)) {
                                System.out.println("Match found - Mapping " + sCurrentLine + i);
                                if (mapperValue.contains("[EVENT=agentStateEvent]")) {
                                    outputFirst += mapperValue.trim() + "\r\n";
                                    counter++;
                                } else if (mapperValue.contains("[EVENT=TerminalConnectionCreated]")) {
                                    outputSecond += mapperValue.trim() + "\r\n";
                                    counter++;
                                } else {
                                    outputThird += mapperValue.trim() + "\r\n";
                                    counter++;
                                }
                            }
                        }
                    } 
                    catch (Exception e) 
                    {
                        System.err.println("Error: "+sCurrentLine + " " + mapperValue);
                    }
                }
            }
            System.out.println("writing final record out");
            writer.write(outputFirst + outputSecond + outputThird);
            writer.close();
            System.out.println("complete!");
            System.out.print("Time taken: " + 
            ((TimeUnit.MILLISECONDS.toMinutes(System.currentTimeMillis())-TimeUnit.MILLISECONDS.toMinutes(timer)))
            + " minutes");
        } 
        catch (Exception e) 
        {
            System.err.println("Error: Target File Cannot Be Read");
        }
    }
}
  • 问题所在?

我曾尝试在谷歌和论坛上查看其他解决方案,但无法找到合适或更快的方法来执行此操作(或超出我的知识深度)。每个时间戳循环通过 1100 万行大约需要 10 分钟,如果有 10,000 个时间戳,您可以想象这个过程需要多长时间。有人可以向我提供一些关于在哪里查找或任何可以加快此过程的 API 的友好建议吗?

【问题讨论】:

  • 您是否考虑过为条目使用数据库而不是文本文件?
  • 嗨 Roman,我使用 SQL 服务器之类的 DB 时唯一担心的是,这 1100 万多行中的每一行都包含远高于每行 20,000 个字符的字符。我想知道这是否会成为 SQL 的问题?
  • 为搜索到的文件创建index
  • 嗨@MubeenHussain 希望此链接对您有所帮助:codereview.stackexchange.com/questions/44021/…
  • 你检查过 Apache Commons IO,commons.apache.org/proper/commons-io/description.html 吗? (见行迭代器)但是我认为我们的问题不是阅读,而是每一行的处理。你想用一条线做什么?

标签: java


【解决方案1】:

感谢大家的建议。肯定会尝试 Roman 提出的数据库方法,因为它对于我正在尝试做的工作类型可能是最快的,但如果没有成功将尝试提出的其他解决方案:)

【讨论】:

    猜你喜欢
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多