2011-06-28 9 views
2

逆の順序(Javaの場合)で新しいファイルを作成したいという非常に大きなファイル(1Gかもしれない)があります。たとえば :逆の順序でファイルを読み書きする - Java

Original file: 

This is the first line 
This is the 2nd line 
This is the 3rd line 

The reversed file: 

This is the 3rd line 
This is the 2nd line 
This is the first line 

ファイルを一度にメモリにファイル全体をロードし、順番は問題があるかもしれない反転、非常に大きいので、(私が使用できるメモリには限界があります)。 これをJavaでどのように達成できますか?

ありがとうございました

+0

これは私に100Gbの行をソートしなければならなかった(おそらくインタビューの)質問を思い出させます(見つけられない、http://programmers.stackexchange.comのどこかにあったと思います) 1GbのRAMのみを使用して120Gbディスクにテキストファイルを作成します。 – Qwerky

答えて

6

非常に直接、私は恐れています。しかし、RandomAccessFileをラップするReverseBufferedReadクラスを簡単に作成できます。

hereも参照してください。

0

ファイルの読み取り方法はわかっていると思います。私はそれを行うことをお勧めする1つの方法は、ジェネリック型の文字列のArrayListです。したがって、ファイルの各行を読み、それをそのリストに格納します。読んだら、リストを印刷したり、何でもしたいことをしてください。

はちょうどここに助けになるかもしれない何かを書いた:逆の順序でファイルライン・バイ・ラインを読むhttp://pastebin.com/iWTVrAvm

+0

ありがとうございますが、ここで問題となるのは、ファイル全体をメモリにロードできないため、このソリューションを使用できないことです。 – Liz

1

は基本的にトリッキーです。

固定幅のエンコーディングがある場合は、tooもありません。可変幅のエンコーディングを使用して、その他の最初のバイト(たとえばUTF-8)を検出できる場合は可能です。エンコーディングが可変幅であり、境界を判断する賢明な方法がない場合(または、例えば「シフト」を使用する場合)、効率的に行うことは事実上不可能です。

私はC#in another questionで実装していますが、それをJavaに移植するにはかなりの労力がかかります。

5

数百行のチャンクでファイルを読み取り、チャンク内の行の順序を逆にして一時ファイルに書き出します。次に、一時ファイルを逆の順序で結合してクリーンアップします。

つまり、メモリの代わりにディスクを使用します。 RandomAccessFileを使用して

0

読む - randomAccesFile.lengthを(使用してファイルを配置)し、あなたがleonbloyようにRandomAccessFileを使用する場合はBufferedWriter

+1

RandomAccessFileの場合、「メモリの懸念のためにバッファされたクラスをラップする」とはどういう意味ですか? RandomAccessFileはBufferedReaderをラップすることはできません(もちろん、私はBufferedReaderから読み込むことはできません...)ので、ここで何を意味するのか分かりません。 – Liz

+0

あなたは正しいです。私はその行を削除するために私の応答を編集しました。 –

1

を使用して書き込み、ファイルの末尾にスキップしFileChannel

を使用することができます示唆しましたその行を読み込んで別のファイルに書き込むことができます。

ここでのJavaのチュートリアルでは、簡単な例があります:example

2

は、私は、出力のためのRandomAccessFileを作成し、それを適切なサイズにするためにはsetLength()を使用して提案します。

その後、元のファイルをスキャンし、RandomAccessFileの最後から逆にチャンクで書き出します。

のJavaっぽい擬似:

out.seek(size_of_out_file); //seek to end 
RandomAccessFile out = new RandomAccessFile("out_fname", "rw"); 
out.setLength(size_of_file_to_be_reversed) 
File in = new File ("in_fname"); 
while (hasMoreData(in)){ 
    String chunk = in.readsize(); 
    out.seekBackwardsBy(chunk.length()); 
    out.write(chunk.reverse); 
    out.seekBackwardsBy(chunk.length()); 
} 
関連する問題