1

私はJavaが初めてで、テキストファイルのパスという1つの引数を持つプログラムを作成しようとしています。プログラムはテキスト ファイルを検索し、画面に出力します。最終的には、これをビルドして、指定されたテキスト ファイルをフォーマットし、それを出力ファイルに出力しますが、それについては後で説明します。

とにかく、私のプログラムは常に IOException をスローしていますが、その理由はわかりません。引数 C:\JavaUtility\input.txt を指定すると、実行時に「エラー、ファイルを読み取れませんでした」というメッセージが表示されます。私のコードは以下にあります。

import java.io.*;

public class utility {
    public static void main(String[] path){

        try{

        FileReader fr = new FileReader(path[0]);
        BufferedReader textReader = new BufferedReader(fr);

        String aLine;

        int numberOfLines = 0;
        while ((aLine = textReader.readLine()) != null) {
            numberOfLines++;
        }

        String[] textData = new String[numberOfLines];

        for (int i=0;i < numberOfLines; i++){
            textData[i] = textReader.readLine();
        }

        System.out.println(textData);

        return;
        }
        catch(IOException e){
            System.out.println("Error, could not read file");

        }       
    }       
}

[編集] 皆様、ご協力ありがとうございました! したがって、私の最終目標を考えると、行数を見つけて有限配列に格納することは依然として有用であると考えました。それで、私は2つのクラスを書くことになりました。1つ目はReadFile.java、必要なデータを見つけて、ほとんどの読み取りを処理します。2 つ目FileData.javaは、ReadFile のメソッドを呼び出して出力します。後で誰かが役に立つと思った場合に備えて、以下に投稿しました。

package textfiles;
import java.io.*;

public class ReadFile {

        private String path;

        public ReadFile(String file_path){
            path = file_path;
        }

        int readLines() throws IOException{

            FileReader file_to_read = new FileReader(path);
            BufferedReader bf = new BufferedReader(file_to_read);

            String aLine;
            int numberOfLines = 0;

            while ((aLine = bf.readLine()) != null){
                numberOfLines++;
            }
            bf.close();
            return numberOfLines;
        }

        public String[] OpenFile() throws IOException{

            FileReader fr = new FileReader(path);
            BufferedReader textReader = new BufferedReader(fr);

            int numberOfLines = readLines();
            String[] textData = new String[numberOfLines];

            for(int i=0; i < numberOfLines; i++){
                textData[i] = textReader.readLine();
            }

            textReader.close();
            return textData;
        }
}


package textfiles;
import java.io.IOException;

public class FileData {

    public static void main(String[] args)throws IOException{

        String file_name = args[0];

        try{
            ReadFile file = new ReadFile(file_name);
            String[] aryLines = file.OpenFile();

            for(int i=0; i < aryLines.length; i++){
                System.out.println(aryLines[i]);
            }


        }

        catch (IOException e){
            System.out.println(e.getMessage());
        }


    }
}
4

3 に答える 3

6

あなたはファイルの終わりにいます。ファイルの行数を決定するときは、ファイルの終わりまで読みEOF Flagが設定されます。[編集:@EJPが以下に示すようにBufferedReader、ファイルの終わりを超えてnullの読み取り値を返します。ただし、読者が希望する場所にいないという事実は真実のままです。]以前は、ファイルを閉じて再度開くだけで、これを回避してきました。Array Listsまたは、または単純に調べますLists。これらは動的にサイズ変更されるため、ファイル内の行数を事前に知る必要はありません。

于 2012-07-20T13:49:40.450 に答える
1

@mikeTheLiarで述べたように、あなたはファイルの終わりにいます。BufferedReader参照は、ファイル内の現在の位置を指す内部カーソルを持つファイルハンドラーです。メソッドを起動readLine()すると、ポインタは改行文字に到達するまで文字を読み取り、文字列を返します。ポインタが新しい位置に設定されます。すべての行を読んだら、をreadLine()返しますnullその後、呼び出すreadLine()とIOExceptionがスローされます。によって指摘されたように@EJP

IO APIを使用する際の最良のコーディングルールの1つは、EOF条件を常にチェックすることです。これは最初のループの場合と同じです。その後EOFに到達したら、カーソルをリセットせずに同じ参照でreadメソッドを呼び出さないでください。これはreset()methodを呼び出すことで実行できます。

私見、あなたの場合、2番目のループは必要ありません。1つのループのみを使用して機能を実現できます。

import java.io.*; 
import java.util.ArrayList;

public class utility { 
public static void main(String[] path){ 

    try{ 

    FileReader fr = new FileReader(path[0]); 
    BufferedReader textReader = new BufferedReader(fr); 

    String aLine; 

    int numberOfLines = 0; 
    ArrayList readLines = new ArrayList();
    while ((aLine = textReader.readLine()) != null) { 
        numberOfLines++; 
        readLines.add(aLine);
    } 
    //Assuming you need array of lines, if not then you can print the lines directly in above loop
    String[] textData = readLines.toArray(); 

    System.out.println(textData); 

    return; 
    } 
    catch(IOException e){ 
        System.out.println("Error, could not read file"); 

    }        
 }     
}

編集

私はあなたのコードを試しました-それはうまく機能していて、配列参照を出力しています。コメントで示唆されているように、問題はソースにあります(セキュリティまたはその他の理由でファイルが読み取れない可能性があります)-例外メッセージを出力して、例外がスローされた正確な行番号を取得できる場合は、役に立ちます。

IO例外以外のいくつかの観察:

ファイルを2回開こうとしています。readLines()メソッドは内から呼び出されますOpenFile()。次のコードファイルはOpenFile()、を作成するときに最初に開かれますtextReader。その後、readLines()作成時にファイルを再度開こうとしているを呼び出していますfile_to_read

あなたはそれを避けるように努めるべきであり、あなたの流れの中であなたはint numberOfLines = readLines();前に電話するべきですFileReader fr = new FileReader(path);

繰り返しになりますが、私見では、メソッドは1つだけであり、効率/パフォーマンスとコードの保守性の両方の観点から、ファイルを1回だけ反復する必要があります。ReadFile次のようにクラスを変更できます。

package textfiles;                     
import java.io.*;
import java.util.ArrayList;                     

public class ReadFile {                     

    private String path;                     

    public ReadFile(String file_path){                     
        path = file_path;                     
    }                     
    //You need not have separate file for counting lines in file
    //Java provides dynamic sized arrays using ArrayList
    //There is no need to count lines             
    public String[] OpenFile() throws IOException{                     

        FileReader fr = new FileReader(path);                     
        BufferedReader textReader = new BufferedReader(fr);                     

        ArrayList fileLines = new ArrayList();
        String readLine = textReader.readLine();
        while(readLine != null){                     
            fileLines.add(readLine);
            readLine = textReader.readLine();                     
        }                     

        textReader.close();                     
        return fileLines.toArray();                     
    }
  }

もう1つの小さな観察:場所によっては、Java変数の命名規則に従わないことがあります。OpenFile()メソッドはあるべきでopenFile()あり、file_to_readあるべきであるfileToRead

于 2012-07-20T14:13:31.743 に答える
0

ここでのいくつかの回答とは対照的に、 readLine() はファイルの最後で例外をスローせず、null を返し続けます。あなたの問題は別の問題によって隠されています。独自のエラー メッセージを作成しないでください。例外に付属するものを常に印刷します。そうすれば、おそらくすぐに問題を見つけることができたでしょう。ほぼ間違いなく、ファイルが存在しないか、読み取りアクセス権がないために、ファイルをまったく開くことができませんでした。例外が教えてくれます。

于 2012-07-20T19:52:40.717 に答える