在Java中读取相对较大的字节文件的最快方法

时间:2012-02-01 10:00:06

标签: java performance file-io

使用Java的I / O方法读取相对较大的文件的最快方法是什么?我当前的解决方案使用BufferedInputStream保存到分配了1024字节的字节数组。每个缓冲区都保存在ArrayList中供以后使用。整个过程通过一个单独的线程(可调用接口)调用。

虽然不是很快。

    ArrayList<byte[]> outputArr = new ArrayList<byte[]>();      
    try {
        BufferedInputStream reader = new BufferedInputStream(new FileInputStream (dir+filename));

        byte[] buffer = new byte[LIMIT]; // == 1024 
            int i = 0;
            while (reader.available() != 0) {
                reader.read(buffer);
                i++;
                if (i <= LIMIT){
                    outputArr.add(buffer);
                    i = 0;
                    buffer = null;
                    buffer = new byte[LIMIT];
                }
                else continue;              
            }

         System.out.println("FileReader-Elements: "+outputArr.size()+" w. "+buffer.length+" byte each.");   

3 个答案:

答案 0 :(得分:36)

我会使用一个内存映射文件,它在同一个线程中足够快。

final FileChannel channel = new FileInputStream(fileName).getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());

// when finished
channel.close();

这假定文件小于2 GB,并且需要10毫秒或更短时间。

答案 1 :(得分:3)

不要使用available():它不可靠。并且不要忽略read()方法的结果:它告诉您实际读取了多少字节。如果你想读取内存中的所有内容,请使用ByteArrayOutputStream而不是使用List<byte[]>

ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read;
while ((read = reader.read(buffer)) >= 0) {
    baos.write(buffer, 0, read);
}
byte[] everything = baos.toByteArray();

我认为1024作为缓冲区大小有点小。我会使用更大的缓冲区(类似16 KB或32 KB)

请注意,Apache commons IO和Guava具有为您执行此操作的实用程序方法,并且已经进行了优化。

答案 2 :(得分:1)

查看Java NIO(非阻塞输入/输出)API。此外,this question可能证明是有用的。

我对IO没有多少经验,但我听说NIO是处理大量数据的更有效方法。