4

大きなファイルを1行ずつ読み取り、重複する行を削除するバッファ付きリーダーがあります。

ファイル全体をメモリにロードする代わりに、2つのバッファリーダーを使用してこれを実行します。最初のリーダーは、ファイルの固定部分を反復処理し、各部分を1つずつメモリにロードします。

各反復で、2番目のバッファリングされたリーダーは、最初のリーダーが停止した場所からファイルの最後まで、ロードされた部分がファイルに存在しないことを確認します。

問題は、最初のオブジェクトが停止した位置から開始するために、新しい独立したバッファリングされたリーダーオブジェクト(参照ではない)を作成できないことです。

最初のバッファリングされたリーダーのファイル位置を見つけて、2番目のバッファリングされたリーダーにどこから始めればよいかを伝える方法が必要です。

私がこれまでに試したこと:

最初のオブジェクトを2番目のコンストラクターに送信します。

これは実際には機能しましたが、両方に同じイテレータがあったため、最初のイテレータは2番目のイテレータとともにファイルの最後に移動しました

BufferedReader cleanfilereader2 = new BufferedReader(cleanfilereader);

bufferedReader.mark()バッファリングされたリーダーの位置を設定しますが、それでも最初のリーダーの位置を知る必要があります。

ノート:

  • 行数は一定ではありません
  • ファイル全体をメモリにロードできません
  • 時間と記憶の両方が問題です
4

4 に答える 4

1

ファイルが大きく、時間が問題になる場合は、すべての行を非常に頻繁に (O(n^2) 回) 読み取る必要があるため、これは最適な方法ではない可能性があります。

そのための十分なメモリがある場合は、ファイルを 1 行ずつ読み取り、各行のハッシュ値を ArrayList に格納することをお勧めします。これには、各行に 4 バイト (1 つの整数) しか必要ありません。次に、この配列リストで重複を検索できます(メモリ内にあるため高速です)。これにより、すべての潜在的な重複のリストが得られ、それらを削除するときに、これらが実際の重複であるかどうかを確認するだけで済みます。

于 2013-01-24T17:21:07.103 に答える
0

現在の位置を読み取る必要がある場合は、FileChannelを 次のように使用できます。

ファイル チャネルには、クエリと変更の両方が可能なファイル内の現在の位置があります。

Channels.newInputStream()InputStreamを使用してチャネルからを作成できます(基になるチャネルを閉じたくない場合は閉じずに) 。

于 2013-01-24T17:14:07.993 に答える
0

これを試してください...(私があなたを正しく理解していれば。)

import java.io.*;
class delete{
public static void main(String args[])throws IOException{
FileInputStream fis1=new FileInputStream("delete.java");
FileInputStream fis2=fis1;
String temp="";
byte buff[]=new byte[100];
while(true){
if (fis1.read(buff)==-1)break;
temp=new String(buff);
System.out.print(temp);
if(fis2.read(buff)==-1)break;
temp=new String(buff);
System.out.print(temp);
}}
}

出力: 上記のコード。

質問は本当に興味深いです。議論のためにコメントしてください。

于 2013-01-24T17:50:10.320 に答える
0

現在の位置を指定する必要BufferedReader.skipがありますが、C のようなものはありません。tellしたがって、BufferedReader を削除し、単純なランダム アクセス ファイル、またはメモリ マップされたファイル バッファである java.nio を使用します。

于 2013-01-24T17:02:10.060 に答える