簡體   English   中英

Java:InputStream讀取大文件太慢了

[英]Java: InputStream too slow to read huge files

我必須按字符讀取53 MB的文件。 當我使用ifstream在C ++中完成它時,它在幾毫秒內完成,但使用Java InputStream需要幾分鍾。 Java很慢或者我錯過了什么是正常的嗎?

另外,我需要用Java完成程序(它使用servlet,我必須從中調用處理這些字符的函數)。 我想也許用C或C ++編寫文件處理部分,然后用Java Native Interface將這些函數與我的Java程序連接......這個想法怎么樣?

任何人都可以給我任何其他提示......我真的需要更快地閱讀文件。 我嘗試使用緩沖輸入,但它仍然沒有提供甚至接近C ++的性能。

編輯:我的代碼跨越幾個文件,它非常臟,所以我給出了概要

import java.io.*;

public class tmp {
    public static void main(String args[]) {
        try{
        InputStream file = new BufferedInputStream(new FileInputStream("1.2.fasta"));
        char ch;        
        while(file.available()!=0) {
            ch = (char)file.read();
                    /* Do processing */
            }
        System.out.println("DONE");
        file.close();
        }catch(Exception e){}
    }
}

我用183 MB文件運行此代碼。 它印有“Elapsed 250 ms”。

final InputStream in = new BufferedInputStream(new FileInputStream("file.txt"));
final long start = System.currentTimeMillis();
int cnt = 0;
final byte[] buf = new byte[1000];
while (in.read(buf) != -1) cnt++;
in.close();
System.out.println("Elapsed " + (System.currentTimeMillis() - start) + " ms");

我會嘗試這個

// create the file so we have something to read.
final String fileName = "1.2.fasta";
FileOutputStream fos = new FileOutputStream(fileName);
fos.write(new byte[54 * 1024 * 1024]);
fos.close();

// read the file in one hit.
long start = System.nanoTime();
FileChannel fc = new FileInputStream(fileName).getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
while (bb.remaining() > 0)
    bb.getLong();
long time = System.nanoTime() - start;
System.out.printf("Took %.3f seconds to read %.1f MB%n", time / 1e9, fc.size() / 1e6);
fc.close();
((DirectBuffer) bb).cleaner().clean();

版畫

Took 0.016 seconds to read 56.6 MB

使用BufferedInputStream

InputStream buffy = new BufferedInputStream(inputStream);

如上所述,使用BufferedInputStream。 您也可以使用NIO包。 請注意,對於大多數文件,BufferedInputStream將與NIO一樣快速讀取。 但是,對於非常大的文件,NIO可能會做得更好,因為您可以進行內存映射文件操作。 此外,NIO包執行可中斷的IO,而java.io包則不執行。 這意味着如果要從另一個線程取消操作,則必須使用NIO使其可靠。

ByteBuffer buf = ByteBuffer.allocate(BUF_SIZE);
FileChannel fileChannel = fileInputStream.getChannel();
int readCount = 0;
while ( (readCount = fileChannel.read(buf)) > 0) {
  buf.flip();
  while (buf.hasRemaining()) {
    byte b = buf.get();
  }
  buf.clear();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM