14

53MBのファイルを1文字ずつ読み取る必要があります。ifstreamを使用してC++で実行すると、ミリ秒単位で完了しますが、JavaInputStreamを使用すると数分かかります。Javaがこれほど遅いのは正常ですか、それとも何かが足りないのでしょうか。

また、Javaでプログラムを完了する必要があります(これらの文字を処理する関数を呼び出す必要があるサーブレットを使用します)。ファイル処理部分を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){}
    }
}
4

4 に答える 4

15

このコードを183MBのファイルで実行しました。「250ms経過」と印刷されました。

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");
于 2012-05-06T20:36:29.283 に答える
3

私はこれを試してみます

// 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
于 2012-05-06T20:42:08.987 に答える
2

を使用しBufferedInputStreamます:

InputStream buffy = new BufferedInputStream(inputStream);
于 2012-05-06T20:14:50.613 に答える
1

上記のように、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();
}
于 2012-05-06T20:35:13.310 に答える