内存映射文件位置

Memory Mapped File location

我正在尝试搜索包含 268 000 个单词的列表。这个想法是检查用户输入的单词是否存在于该列表中。我使用简单的 I/O 流完成了此操作,但搜索大约需要 5 秒,这太长了。我的文件当前位于资产中。我一直在寻找更有效的方法来搜索我的文件,并且遇到了 Memory Mapped Buffer。但是,我不清楚在以下示例中我应该将文件存储在哪里:

    import java.io.File;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;

    public class ReadFiles {
        private static String largeFile = "sowpods.txt";

        public static void read() throws IOException {
            File file = new File(largeFile);
            FileChannel fileChannel = new 
            RandomAccessFile(file,"r").getChannel();
            MappedByteBuffer buffer = fileChannel.map(
            FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
            System.out.println(buffer.isLoaded());
            System.out.println(buffer.capacity());
        }
    }

如果我把它留在资产中,我该如何读取它?目前,我收到一条 "sowpods.txt: open failed: ENOENT (No such file or directory)" 错误消息。感谢您的任何提示!

在这里使用内存映射文件不是一个好主意。您实际上是在浪费 OS 资源,而且它无论如何也不会让您获得最佳速度。

如果您只是偶尔执行一次搜索,希望保持简单并且不想在搜索之间将文件保留在内存中,请使用 BufferedInputStream。给它一个缓冲区,比如 10 kB,它应该执行得相当快,而且很可能会使磁盘饱和。

如果您执行大量搜索,请尝试在搜索之间将内容保存在内存中。使用 HashSet 或 TreeSet。如果您使用的是 HashSet,请为其提供足够的存储桶。

如果 none 适合您(即您内存不足,您有数百万个单词并且仍然想要快速搜索),将这些单词转换为某个 SQL 数据库,将数据放入在 table 中并对其进行索引。这确实是数据库 excel 所在的位置。您应该可以轻松找到适合您目的的数据库。

显然,30 万个单词并不多,内存应该很容易容纳,大约 10 MB。根据您的使用场景,您可能还想查看 Bloom filter.

这是一个例子。

  /** Memory-map the model file in Assets. */
  private MappedByteBuffer loadModelFile(Activity activity) throws IOException {
    AssetFileDescriptor fileDescriptor = activity.getAssets().openFd(getModelPath());
    FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
    FileChannel fileChannel = inputStream.getChannel();
    long startOffset = fileDescriptor.getStartOffset();
    long declaredLength = fileDescriptor.getDeclaredLength();
    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
  }
  @Override
  protected String getModelPath() {
    // you can download this file from
    // see build.gradle for where to obtain this file. It should be auto
    // downloaded into assets.
    return "mobilenet_v1_1.0_224.tflite";
  }

mobilenet_v1_1.0_224.tflite 文件已粘贴到资产中。