2014-01-17 26 views
2

我正在寻找最快的方式读取文件 - 我不需要看到读取字节,我只需要文件被完全读取,以便它获取OS文件缓存。最快的方式读取文件到操作系统文件缓存

这是我在用的时刻(但它涉及到分配为每个文件直接缓存)

FileInputStream f = new FileInputStream(file); 
    FileChannel ch = f.getChannel(); 
    ByteBuffer bb = ByteBuffer.allocateDirect((int)file.length()); 
    ch.read(bb); 
+3

你当前的实现是错误的 - 如果文件的大小是1G,你的缓冲区分配将失败,而是分配一个合理大小为X的缓冲区并在循环中读取你的文件。 PS:为什么地球上你想要缓存中的文件?即使你加载它,也绝对不能保证它在你需要时仍然存在。 –

+0

是的,好点。我在我的代码中纠正了它。我为什么要这样做?因为我有一个使用NIO通过套接字从DVD传输文件的Java库。由于某些原因,从DVD传输时速度非常慢,但当文件位于Windows文件缓存中时速度非常快。所以,我的解决方案是读取50 MB的文件,然后使用该库传输它们(当我确定它们被缓存时)。 – Jacko

+1

好吧,总的时间(从DVD - >到缓存+从缓存 - >连接的另一端)仍然大致相同,因为(因为我不了解你)瓶颈是从DVD读取。 –

回答

-2

感谢EJPs建议,我创建了自己的/ dev/null的文件通道:

RandomAccessFile racFile = new RandomAccessFile(file, "r"); 
    FileChannel ch = racFile.getChannel(); 
    ch.transferTo(0, fileLength, new WritableByteChannel(){ 

    @Override 
    public boolean isOpen() { 
     // TODO Auto-generated method stub 
     return true; 
    } 

    @Override 
    public void close() throws IOException { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public int write(ByteBuffer src) throws IOException { 
     // TODO Auto-generated method stub 
     int rem = src.remaining(); 
     return rem; 
    } 

    } 

    ); 
    racFile.close(); 

这提供了在我的基准测试中最快的解决方案。

+0

这不是我的建议。操作系统已经提供了这样的设备。没有必要编写代码来实现这一点,就像我在答案中所说的那样。如果你这样做,只需将数据复制到该设备。你不必自己创造。 – EJP

+0

是的,我必须发明自己的。你的建议没有奏效。这是我能找到的最佳解决方案。 – Jacko

2

只要将它与cat,\nulcopy在Windows上复制到/dev/null。根本不需要编写任何代码。

+0

谢谢,EJP。你的建议引发了为我解决它的想法。但是,为每个文件启动一个进程对我来说似乎并不理想。 – Jacko

+0

@Jacko我没有说每个文件的进程。这两个程序都可以在每个调用中复制多个文件。 – EJP