2011-12-14 15 views
3

wiki.txtファイルがあり、そのサイズは50 MBです。テキストファイルをJavaのメモリにロード

  1. 正しいということですが、私は、ファイルにいくつかのことを行う必要がありますので、私はパフォーマンスの面で最善の方法は、メモリにファイルをロードすることであると思いましたか? mapByteBuffer.get():私はこのコードのエラーを取得します

    File file = new File("wiki.txt"); 
    FileInputStream fileInputStream = new FileInputStream(file); 
    FileChannel fileChannel = fileInputStream.getChannel(); 
    MappedByteBuffer mapByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 
    System.out.println((char)mapByteBuffer.get()); 
    

  • は、これは私が書いたコードです。 get()関数にいくつかのオプションを試しましたが、それらのすべてがエラーになり、e.getMessage()でエラーが発生しませんでした。

    私のテキストファイルには英語の単語が含まれています。私がする必要のある操作は、このテキストファイルに存在すると検索されたものです。

    ありがとうございます。

  • +2

    どのエラーが表示されますか? – bvd

    +0

    あなたが受け取ったエラーメッセージを投稿してください。また、テキストファイルからいくつかのサンプルラインを見ることができます。効率的な読み書き方法を提案することができます。 –

    答えて

    3

    私はそれをメモリにロードするのではなく、ディスクから直接ファイルを読み取るために、メモリマップトファイルを使用してお勧めします。

    RandomAccessFile file = new RandomAccessFile("wiki.txt", "r"); 
    FileChannel channel = file.getChannel(); 
    MappedByteBuffer buf = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024*50); 
    

    そして、いつものようにバッファを読み取ることができます。

    +0

    しかし、ここで私にお勧めします毎回50Kを読んで、この小さなバッファで検索しますか? 2回目、3回目...検索回数を増やす必要があります。ファイルの最後(50MB)に戻るまで、50Kロードをすべて行いますか? –

    1

    私はBufferedReaderを使用することをお勧めします。それははるかに高速で、比較的少ないリソースしか必要としません。ラインの 最初の読み出し番号:

    InputStream is = new BufferedInputStream(new FileInputStream(filename)); 
    byte[] chars = new byte[1024]; 
    int numberOfChars = 0; 
    while ((numberOfChars = is.read(chars)) != -1) 
    { 
        for (int i = 0; i < numberOfChars; ++i) 
        { 
         if (chars[i] == '\n' && numberOfChars - i != 1) 
         { 
          ++count; 
         }   
        } 
    } 
    count++ 
    return count; // number of lines 
    

    はその後の行を読んで:あなたも、あなたが必要なものを検索することができます。この文字列で

    BufferedReader in = new BufferedReader(new FileReader(fileName)); 
    for (int i = 0; i < endLine; i++) 
    { 
        String oneLine = in.readLine(); 
    } 
    

    +0

    しかし、私はいくつかの異なる表現を検索する必要があります。ファイル全体をもう一度見ていると、本当によかったですか? –

    +0

    良い考えではありません。 文字列が50MBファイルの最後にある場合、これには長い時間がかかります。 –

    2

    ポイントのための私の答えは(1):

    それはあなたがファイルに何をしたいかに依存します。処理の巻き戻し操作が含まれていない場合(読み込み中/読み込み中)は、ストリームとして読み込み、すべてをメモリにロードするのではなく、一度に処理することをお勧めします。

    あなたのソリューションは、ときだけでなく、より大きなサイズのファイルサイズの変更をスケーリングない可能性があるため、ファイル全体でランダムアクセスを必要とする場合でも、あなたはまた、ブロックのファイル操作をすることに興味があるかもしれません。 Java 1.4以上であれば RandomAccessFileです。 ランダムアクセスの場合、オペレーティングシステムは通常、ファイルバッファのキャッシュを処理します。自分で処理する必要はありません。

    +0

    私は式(いくつかの単語を含むことができる文字列)を取得し、式がテキストファイル内にあるかどうかを返す必要があります。そして、私はこの操作を異なる表現で繰り返しますが、同じテキストファイルで繰り返さなければなりません。 –

    +0

    あなたの要件は、文字列の検索と文字列のマッチングのように私に聞こえるようになりました。いくつかの前処理をしても繰り返す必要はありません。私はKnuth-Morris-Pratt(http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm)のような文字列検索アルゴリズムを見てみることをお勧めします。 –

    2

    メッセージだけでなく、エラー全体を読むことが重要です。多くの場合、実際の情報は例外の名前に関連付けられているテキストではありません。

    最初のバイトがないため、ファイルが空の場合はエラーが発生します。

    注:使用しているアプローチは、ASCII 7ビット文字を前提としています。 ISO-8859-1文字を使用したい場合は、(char) (byteBuffer.get() & 0xFF)

    となりますが、文字列を使用すると、使用するのが簡単になり、速度もそれほど遅くならないことがあります。例えば1秒未満でテキストとして50 MBのファイルを読むことができます。これはあまりにも長い場合私はメモリマップされたファイルを使用します。

    関連する問題