web-dev-qa-db-ja.com

Javaでファイルポインタをファイルの先頭にリセットするにはどうすればよいですか?

Javaで、2つのファイルのデータを比較する必要があるプログラムを書いています。ファイル1の各行をファイル2の各行と照合し、一致するものが見つかった場合はそれらを書き込む必要があります。ファイル2の最後まで読んだ後、ポインタをファイルの最初にリセットするにはどうすればよいですか?

public class FiFo {
    public static void main(String[] args) 
    {
        FileReader file1=new FileReader("d:\\testfiles\\FILE1.txt");
        FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
        try{
            String s1,s2;
            while((s1=file1.data.readLine())!=null){
                System.out.println("s1: "+s1);
                while((s2=file2.data.readLine())!=null){
                    System.out.println("s2: "+s2);
                }
            }
            file1.closeFile();
            file2.closeFile();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class FileReader {
    BufferedReader data;
    DataInputStream in;

    public FileReader(String fileName)
    {
        try{
            FileInputStream fstream = new FileInputStream(fileName);
            data = new BufferedReader(new InputStreamReader(fstream));
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    } 

    public void closeFile()
    {
        try{
            in.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
12
Shaz

RandomAccessFile が必要だと思います。含まれているもの:_RandomAccessFile#seek_および_RandomAccessFile#getFilePointer_。

rewind()seek(0)です

13

最善の方法は、ファイル1の各行をHashMapに入れることだと思います。次に、ファイル1の各行に対してファイル全体を1回読み取るのではなく、ファイル2の各行のHashMapのメンバーシップを確認できます。

ただし、ファイルの先頭に戻る方法についての質問に答えるには、別のInputStream/Readerを開くのが最も簡単な方法です。

5
danben

明らかに、次のようにファイルを閉じて再度開くことができます。

     while((s1=file1.data.readLine())!=null){
         System.out.println("s1: "+s1);
         FileReader file2=new FileReader("d:\\testfiles\\FILE2.txt");
         while((s2=file2.data.readLine())!=null){
             System.out.println("s2: "+s2);
             //compare s1 and s2;
         }
         file2.closeFile()
     }

しかし、このアルゴリズムの実行時間はO(n)であるため、実際にはそのようにはしたくありません。2)。ファイルAに1000行、ファイルBに10000行ある場合、内部ループは1,000,000回実行されます。

あなたがすべきことは、各行を読んでそれをコレクションに保存することです。これにより、アイテムがすでに含まれているかどうかをすばやく確認できます(おそらくHashSet)。

ファイル2のすべての行がファイル1にあることを確認するだけでよい場合は、ファイル1の各行をHashSetに追加してから、ファイル2のすべての行がそのセットにあることを確認します。

一方にあるが他方にはないすべての文字列を見つける相互比較を行う必要がある場合は、ファイルごとに1つずつ、2つのハッシュセットが必要になります。 (1つだけを使用するためにできるトリックがありますが)

ファイルが大きすぎて十分なメモリがない場合は、元のn2 とにかく方法は決してうまくいきませんでした。

2
Chad Okere

さて、Gennady S.の答えは、私があなたの問題を解決するために使用するものです。

Javaで、2つのファイルのデータを比較する必要があるプログラムを書いています。

ただし、これを再度コーディングするのではなく、次のようなものを使用します http://code.google.com/p/Java-diff-utils/

1
Ryan Fernandes

前述のように、より良いアルゴリズムがあります-これらを調査してください

余談:

FileReaderはマークとリセットを実装していないため、trashgodのコメントは不正確です。これのバージョンを実装するか(RandomAccessFileなどを使用して)、BufferedReaderでラップする必要があります。ただし、後者は、マークを付けるとすべてをメモリにロードします

0
MJB

簡単な質問です。 1つのオブジェクトをファイルの先頭に向けたままにして、別のオブジェクトでファイルをトラバースすることはできませんか?次に、最後に到達したら、ファイル(ストリーム)の先頭にあるオブジェクトをポイントします。 C++にはファイルI/O(またはストリームI/O)を備えたそのようなメカニズムがあると思います

0
Dark Star1

ファイルポインタをファイルの先頭にリセットするだけの場合は、バッファリーダーを再初期化します。また、ファイルの終わりをチェックするためにtry andcatchブロックも使用していると思います。

`//To read from a file. 
      BufferedReader read_data_file = new BufferedReader(new FileReader("Datafile.dat"));'

これが、バッファリーダーを定義する方法であるとしましょう。これが、file = nullの終わりを確認する方法です。

boolean has_data= true;

while(has_data)
     {    
      try
     {
     record = read_data_file.readLine();
     delimit = new StringTokenizer(record, ",");
     //Reading the input in STRING format. 
     cus_ID = delimit.nextToken();
     cus_name = delimit.nextToken();'
      //And keep grabbing the data and save it in appropriate fields. 
     }
catch (NullPointerException e)
     {
      System.out.println("\nEnd of Data File... Total "+ num_of_records 
                       + " records were printed. \n \n");
      has_data = false; //To exit the loop. 
      /*
        ------> This point is the trouble maker. Your file pointer is pointing at the end of the line. 
     -->If you want to again read all the data FROM THE TOP WITHOUT   RECOMPILING: 
      Do this--> Reset the buffer reader to the top of the file.
      */                      
      read_data_file = new BufferedReader(new FileReader(new File("datafile.dat")));
}

バッファリーダーを再初期化することにより、ファイルリーダーのマーク/ポインターをファイルの先頭にリセットし、ファイルを再コンパイルしてファイルリーダーのマーカー/ポインターをファイルの先頭/先頭に設定する必要がなくなります。同じ実行で同じスタントを再コンパイルしてプルオフしたくない場合にのみ、バッファーリーダーを再初期化する必要があります。ただし、ループを1回だけ実行する場合は、すべてを実行する必要はありません。ファイルを再コンパイルするだけで、ファイルリーダーマーカーがファイルの先頭/先頭に設定されます。

0
Parth Shah

ファイル2ファイルリーダーを再初期化するだけで、リセットできると思います。

0

ファイルのdimensionを明確に識別できる場合は、クラスからmark(int readAheadLimit)およびreset()を使用できますBufferedReader。メソッドmark(int readAhedLimit) BufferedReaderの現在の位置にマーカーを追加すると、reset()を使用してマーカーに戻ることができます。

それらを使用するには、注意までに読み取る文字数にreset()、関数の引数として指定する必要がありますmark (int readAhedLimit)

100文字の制限があるとすると、コードは次のようになります。

class MyFileReader {
    BufferedReader data;
    int maxNumberOfCharacters = 100;

    public MyFileReader(String fileName)
    {
        try{
            FileInputStream fstream = new FileInputStream(fileName);
            data = new BufferedReader(new InputStreamReader(fstream));
            //mark the current position, in this case the beginning of the file
            data.mark(maxNumberOfCharacters);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void resetFile(){
        data.reset();
    }

    public void closeFile()
    {
        try{
            in.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}
0
Niles

他の人が示唆しているように、問題に対する他のアプローチを検討する必要があります。ファイル内の前のポイントに戻るという特定の質問については、 _Java.io.FileReader_mark() および reset() この目標に対処するメソッド。

0
trashgod