Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中8GB平面文件中无序的名称列表中查找名称_Java_Performance_Io - Fatal编程技术网

如何在Java中8GB平面文件中无序的名称列表中查找名称

如何在Java中8GB平面文件中无序的名称列表中查找名称,java,performance,io,Java,Performance,Io,好的,我们有这个问题,我知道我可以使用InputStream来读取流,而不是读取整个文件,因为这会导致内存问题 关于这一答复: 然而,问题是速度,在本例中,我将读取整个文件的每一行。考虑到此文件以无序方式包含数百万个名称,并且此操作必须在几秒钟内完成,我如何着手解决此问题。由于列表无序,因此除了读取整个文件之外,别无选择 如果你幸运的话,第一个名字就是你要找的名字:o(1) 如果你不走运,那就是姓:O(n) 除此之外,无论您使用java.io方式(Files.newbufferederader(

好的,我们有这个问题,我知道我可以使用InputStream来读取流,而不是读取整个文件,因为这会导致内存问题

关于这一答复:


然而,问题是速度,在本例中,我将读取整个文件的每一行。考虑到此文件以无序方式包含数百万个名称,并且此操作必须在几秒钟内完成,我如何着手解决此问题。

由于列表无序,因此除了读取整个文件之外,别无选择

如果你幸运的话,第一个名字就是你要找的名字:o(1)

如果你不走运,那就是姓:O(n)

除此之外,无论您使用
java.io
方式(
Files.newbufferederader()
)还是
java.nio
方式(
Files.newByteChannel()
),它们都或多或少地执行相同的操作。如果输入文件是基于行的(如您的情况),则可以使用

Files.lines().filter(l -> name.equals(l)).findFirst();
它在内部使用一个BufferedReader

如果您真的不想加快速度,那么您必须对文件中的名称进行排序(请参阅),现在您可以从

编辑:使用索引的有序列表 一旦您有了一个有序列表,您就可以使用
树形图快速扫描并创建索引,然后右键跳转到正确的文件位置(使用
随机访问文件
seekablebytechnel
)并读取名称

例如:

long blockSize = 1048576L;
Path file = Paths.get("yourFile");

long fileSize = Files.size(file);
RandomAccessFile raf = new RandomAccessFile(file.toFile(), "r");

//create the index
TreeMap<String, Long> index = new TreeMap<>();
for(long pos = 0; pos < fileSize; pos += blockSize) {
     //jump the next block
     raf.seek(pos);
     index.put(raf.readLine(), pos);
 }

 //get the position of a name
 String name = "someName";

 //get the beginning and end of the block
 long offset = Optional.ofNullable(index.lowerEntry(name)).map(Map.Entry::getValue).orElse(0L);
 long limit = Optional.ofNullable(index.ceilingEntry(name)).map(Map.Entry::getValue).orElse(fileSize);

 //move the pointer to the offset position
 raf.seek(offset);
 long cur;
 while((cur = raf.getFilePointer())  < limit){
      if(name.equals(raf.readLine())) {
          return cur;
      }
 }
long blockSize=1048576L;
Path file=Path.get(“yourFile”);
long fileSize=Files.size(文件);
RandomAccessFile raf=新的RandomAccessFile(file.toFile(),“r”);
//创建索引
树映射索引=新树映射();
用于(长pos=0;pos

块大小是索引大小、索引创建时间和数据访问时间之间的折衷。块越大,索引和索引创建时间越短,但数据访问时间越长。

由于列表无序,因此除了读取整个文件之外别无选择

如果你幸运的话,第一个名字就是你要找的名字:o(1)

如果你不走运,那就是姓:O(n)

除此之外,无论您使用
java.io
方式(
Files.newbufferederader()
)还是
java.nio
方式(
Files.newByteChannel()
),它们都或多或少地执行相同的操作。如果输入文件是基于行的(如您的情况),则可以使用

Files.lines().filter(l -> name.equals(l)).findFirst();
它在内部使用一个BufferedReader

如果您真的不想加快速度,那么您必须对文件中的名称进行排序(请参阅),现在您可以从

编辑:使用索引的有序列表 一旦您有了一个有序列表,您就可以使用
树形图快速扫描并创建索引,然后右键跳转到正确的文件位置(使用
随机访问文件
seekablebytechnel
)并读取名称

例如:

long blockSize = 1048576L;
Path file = Paths.get("yourFile");

long fileSize = Files.size(file);
RandomAccessFile raf = new RandomAccessFile(file.toFile(), "r");

//create the index
TreeMap<String, Long> index = new TreeMap<>();
for(long pos = 0; pos < fileSize; pos += blockSize) {
     //jump the next block
     raf.seek(pos);
     index.put(raf.readLine(), pos);
 }

 //get the position of a name
 String name = "someName";

 //get the beginning and end of the block
 long offset = Optional.ofNullable(index.lowerEntry(name)).map(Map.Entry::getValue).orElse(0L);
 long limit = Optional.ofNullable(index.ceilingEntry(name)).map(Map.Entry::getValue).orElse(fileSize);

 //move the pointer to the offset position
 raf.seek(offset);
 long cur;
 while((cur = raf.getFilePointer())  < limit){
      if(name.equals(raf.readLine())) {
          return cur;
      }
 }
long blockSize=1048576L;
Path file=Path.get(“yourFile”);
long fileSize=Files.size(文件);
RandomAccessFile raf=新的RandomAccessFile(file.toFile(),“r”);
//创建索引
树映射索引=新树映射();
用于(长pos=0;pos

块大小是索引大小、索引创建时间和数据访问时间之间的折衷。块越大,索引和索引创建时间越短,但数据访问时间越长。

我建议将数据移动到数据库(签出SQLite以获得无服务器选项)

如果不可能,您可以尝试让多个线程读取文件,每个线程从文件中的不同偏移量开始,并且只读取文件的一部分


你将不得不使用一种新的方法。这只有在您使用RAID系统时才有好处,正如这里的基准:

我建议将数据移动到数据库(签出SQLite以获得无服务器选项)

如果不可能,您可以尝试让多个线程读取文件,每个线程从文件中的不同偏移量开始,并且只读取文件的一部分


你将不得不使用一种新的方法。这只有在您使用RAID系统时才有好处,正如这里的基准:

因为您的标题是“无序”,所以除了读取整个文件之外,您没有其他选择(最坏的情况)。您可以在循环中添加一个
break
,然后找到名称。但这只有在不是姓氏的情况下才有帮助。您想只搜索一次还是多次?为什么不能对列表进行排序?只需搜索一次,因为您的标题是“无序”,除了读取整个文件之外,您没有其他选择(最坏的情况)。您可以在循环中添加一个
break
,然后找到名称。但这只有在不成功的情况下才会有所帮助