Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.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内存映射二进制搜索_Java_Nio_Mmap - Fatal编程技术网

Java内存映射二进制搜索

Java内存映射二进制搜索,java,nio,mmap,Java,Nio,Mmap,我目前正在寻找在java中搜索2GB二进制文件的最快方法。这与我的正常问题不同,因为该文件已使用mmap将内存映射到Linux文件系统 这个文件是一个二进制文件,我需要搜索一个固定的四字节字符串AXL0 通常,对于较小的文件,我只需缓冲它,将其转换为字符串,然后对其进行正则化。然而,由于这个文件已经被内存映射,而且相当大,重新缓冲它的想法似乎是错误的,并且将它转换成2GB字符串的想法似乎更错误 经过一些阅读,我发现了JavaNIO包以及FileChannel和MappedByteBuffers,

我目前正在寻找在java中搜索2GB二进制文件的最快方法。这与我的正常问题不同,因为该文件已使用
mmap
将内存映射到Linux文件系统

这个文件是一个二进制文件,我需要搜索一个固定的四字节字符串<代码>AXL0

通常,对于较小的文件,我只需缓冲它,将其转换为字符串,然后对其进行正则化。然而,由于这个文件已经被内存映射,而且相当大,重新缓冲它的想法似乎是错误的,并且将它转换成2GB字符串的想法似乎更错误

经过一些阅读,我发现了Java
NIO
包以及
FileChannel
MappedByteBuffers
,但我不完全确定如何设置它们

我只需要扫描文件,从零到文件中的最后一个字节,并找到四字节字符串的每个实例

如果有人能提供一些建议或意见,我将不胜感激


谢谢。

从抽象的角度看任务,没有什么比线性搜索更好的了

从下面的内容来看,实际执行搜索所使用的API可能并不重要,为简单起见,我将使用缓冲InputStream,它可以不受实际数据源的影响而实现,并且没有阻止它处理大于2GB的文件的固有限制

只要您选择了合理的缓冲区大小(读取:不太小),您就应该获得合理的性能(接近实际I/O速度限制,SSD除外,因为在这种情况下,您的扫描可能需要比实际I/O更长的时间)

编辑:接吻之后,你会得到几行代码,这些代码应该可以很好地完成

public class ScanForByteCombo {

    public static List<Long> scanFor(InputStream is, int needle) throws IOException {
        List<Long> foundOffsets = new ArrayList<>();
        InputStream bs = new BufferedInputStream(is, 0x10000);
        int data = 0;
        int b;
        long offset = 0;
        while ((b = bs.read()) != -1) {
            data = (data << 8) | b;
            if (data == needle) 
                foundOffsets.add(offset);
            ++offset;
        }
        return foundOffsets;
    }

    public static void main(String[] argv) {

        int needle = ('A' << 24) | ('X' << 16) | ('F' << 8) | '0';

        long start = System.currentTimeMillis();
        try (InputStream is = new FileInputStream("your file")) {
            List<Long> found = scanFor(is, needle);
            System.out.println(found);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("scan took " + (System.currentTimeMillis() - start) + "ms. Acceptable?");
    }

}
公共类ScanForByteCombo{
公共静态列表scanFor(InputStream为,int针)引发IOException{
List foundoffset=new ArrayList();
InputStream bs=新的BufferedInputStream(is,0x10000);
int数据=0;
int b;
长偏移=0;
而((b=bs.read())!=-1){

data=(在Grep示例中,有一个将正则表达式与NIO和MappedByteBuffers一起使用的示例(可能会提示如何将其用于二进制文件)也许这会有帮助?这不是内存映射的工作方式。你几乎可以忘记其他程序正在对该文件进行MMA。只需使用一些缓冲读取器读取它,然后逐个查找你的模式。如果你想了解更多信息,请与我联系,我将尝试给出更长的答案。Fox;该文件已作为/tmp映射到Linux文件系统中/scanme,这有什么帮助/阻碍吗?好的,你所说的“映射到文件系统”到底是什么意思?正如oposite(将文件从文件系统映射到内存)所说的那样。你使用什么应用程序/命令来进行映射?如果你在进行真正的二进制搜索,请小心缓冲区边界。如果你要查找的字节跨越边界,你可能会错过它。是的,这是我知道的。我只是在想实现它的最佳方法。我猜是一个固定大小的缓冲区,但这也是h至于边界的问题。@Tony在把它复杂化之前试试KISS版本。参见编辑谢谢你的代码,我会看看我能做些什么。