使用最快的& amp;随机搜索文本文件中的关键字。高效的字符串搜索方法

时间:2016-06-09 04:30:07

标签: java random-access string-search

我有一个文本文件,每行有一条客户记录。每条记录的格式为" ID号,名字,姓氏,金额"。我需要根据用户输入的ID号读取该文本文件的一行。

我一直在关注Java电子书,它通过使用单个记录的长度并将其乘以输入的ID号来完成此操作。问题是,只有每条记录的长度完全相同时才有效。我的记录不会截断或填充名字和姓氏,而美元金额的长度范围是2到5个字符,这意味着图书使用的方法不会起作用。

有没有办法读取文本文件中的特定行而不要求所有记录的长度完全相同?我以为可以使用行分隔符来实现它。

作为参考,我会提供由于我的记录大小不同而无法运行的代码,以防万一。

public static void main(String[] args)
{
  Scanner keyboard = new Scanner(System.in);
  Path filepath = Paths.get("U:\\Programming\\Java\\Chapter 13\\customersdata.txt");
  String s = "  , , , 00.00" + System.getProperty("line.separator");
  final int RECSIZE = s.length();
  byte[] data = s.getBytes();
  ByteBuffer buffer = ByteBuffer.wrap(data);
  FileChannel fc = null;

  try {
     fc = (FileChannel)Files.newByteChannel(filepath, READ, WRITE);
     System.out.println("Enter an ID number to display the customer details for that ID. Or \"quit\".");
     String idString = keyboard.nextLine();

     while(!idString.equals("quit")) {
        int id = Integer.parseInt(idString);
        buffer = ByteBuffer.wrap(data);
        fc.position(id * RECSIZE);
        fc.read(buffer);
        s = new String(data);
        System.out.println("ID #" + id + " " + s);
        System.out.println("Enter an ID number to display the customer details for that ID. Or \"quit\".");
        idString = keyboard.nextLine();
     }
     fc.close();
  }catch(Exception e) {
     System.out.println("Error message: " + e);
  }
}

编辑:由于正在读取的文本文件可能假设包含数万条记录,我无法使用顺序访问,如果我需要的ID号位于文件底部附近,则会出现不可接受的情况所有读取它们的时间,因此,解决方案必须是随机访问。

1 个答案:

答案 0 :(得分:1)

  

我有一个文本文件,每行有一条客户记录。每条记录都是   格式化为" ID号,名字,姓氏,金额"。我需要   根据输入的ID号读取该文本文件的一行   用户。

  

有没有办法在没有文本文件的情况下读取特定行   要求所有记录的长度完全相同?

break;的{​​{1}}方法中,我对main字符串进行了硬编码。您可以根据data.txt更改它并获取数据。

data.txt中

readData("33")

parseTxt.java

id

编辑问题(在保持良好表现的同时进行搜索)

source-1:

1 harry singh 456
2 lauren dat 25
33 pingle pooh 8797
10002 yogeshvari bahman 897461

它需要一些编码,但由于ByteBuffer.allocateDirect,它可以非常快。它允许操作系统直接从文件读取字节到ByteBuffer,而无需复制

source-2: 此链接上的每个答案都会添加一些信息

  1. 将搜索字符串('是')转换为相同的字节数组 编码为文件。
  2. 从文件的文件通道打开内存映射的字节缓冲区。
  3. 扫描ByteBuffer,查找与搜索字节数组的匹配
  4. 随时计算新行。
  5. 关闭ByteBuffer
  6. source-3:

      

    一种比indexOf()快得多的简单技术是使用Scanner,方法是findWithinHorizo​​n()。如果使用带有File对象的构造函数,Scanner将在内部创建一个FileChannel来读取该文件。对于模式匹配,它最终将使用Boyer-Moore算法进行有效的字符串搜索。

    source-4: 实施Boyer-Moore的字符串搜索算法

    对不起,我会把研究留给你。如果你问我的建议,我认为GNU-Grep更快,因为它也使用了Boyer-Moore的字符串搜索算法。 希望这可以帮助!如果我误解了你的问题,请纠正我。