1

ファイル名のプロンプトと受け入れ、そしてファイルテキストをスキャナーオブジェクトにすることについて簡単な質問がありました。

ユーザーが存在するファイルを取得するまでファイルの名前を入力するようにプログラムに促し、ファイルテキストをスキャナーオブジェクトとして使用するようにします。

while {}これは私がこれまでに持っているコードで、ループを終了するところまで機能しますが、スキャナーアイテムをそのようwhile (input.hasNextLine()) {に処理しようとすると、スキャナーアイテムが見つからないというエラーが表示されます。

それはおそらくばかげた間違いですが、私はそれを理解できないようです.

コード全体は次のとおりです。

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

public class PersonalityTest {

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

    boolean isFile = false;

        Scanner sc = new Scanner(System.in);
        System.out.print("Input file name? ");
        String fileName = sc.next();
        File inputFile = new File(fileName);

    while (isFile == false) {    
        if (inputFile.exists()) {
            Scanner input = new Scanner(inputFile);
            isFile = true;
        }            
    }

    while(input.hasNextLine()) {

    }
}
4

4 に答える 4

2

input変数のスコープは while (isFile == false)ブロックに対してローカルです。それ以外の場合は表示されません。

最初の部分「ユーザーが存在するファイルを取得するまで、ファイルの名前を入力するようにプログラムに促したい」: 次のコードを移動します。

    Scanner sc = new Scanner(System.in);
    System.out.print("Input file name? ");
    String fileName = sc.next();
    File inputFile = new File(fileName);

メソッドに挿入し、存在チェックの前にブロック内で呼び出しますwhile (isFile == false)(メソッドはファイルを返すか、他の方法で変数をブロック内で可視にする必要があります)。

于 2012-12-02T07:12:44.047 に答える
1

ステートメントのinput外部にアクセスすることはできません.コンパイラは確信が持てないため、テストに合格します.これを行うことができます:if

Scanner sc = new Scanner(System.in);
Scanner input = null;
boolean isFile = false;

while (isFile == false){    

    System.out.print("Input file name? ");
    String fileName = sc.next();
    File inputFile = new File(fileName);

    if (inputFile.exists()){
        input = new Scanner(inputFile);
        isFile = true;
    }            
}

NullPointerExceptionただし、 の場合はa をスローしnullます。

私はコードを少し変更しました。そのように、ファイルが存在しない場合は超えません。

于 2012-12-02T07:11:32.530 に答える
0

Scannerinputifステートメントに対してローカルです。そのため、あなたのwhile (input.hasNextLine()) {ステートメントは機能しません。Java コンパイラはinput別の Scanner オブジェクトとして扱いますが、ここで問題が発生します。Java コンパイラには、input使用しようとしている が存在しないためです。

上記の問題に遭遇しないため、MouseEventの提案されたコードに従います。

于 2012-12-02T07:20:38.007 に答える
0

他の回答はあなたの差し迫った質問に対処していますが、コードに関する他のいくつかの問題を指摘したいと思います:

ファイルを開くことができるかどうかを確認する方法に欠陥があります。コードを記述するより良い方法は、ファイルを開こうとし、例外が発生したときに再試行することです。例えば:

Scanner input = null;
do {
    System.out.print("Input file name? ");
    String fileName = sc.next();
    File inputFile = new File(fileName);
    try {
        input = new Scanner(inputFile);
    } catch (IOException ex) {
        System.out.println("Cannot open: " + ex.getMessage());
    }          
} while (input == null);

なぜこれは電話よりも優れているのFile.exists()ですか?

  • ファイルを開くことができる理由はたくさんあります。まったく存在しない可能性があります。ファイルとして開くことができないディレクトリまたは特殊なファイルである可能性があります。アプリケーションに権限がない可能性があります。ファイルがリモートでマウントされたファイル システムにあり、リモート マウントが停止した可能性があります。

  • 呼び出し (およびその他の呼び出し) と実際にファイルを開くの間には、わずかな時間差がありFile.exists()ます。その時間のギャップで、プログラムの何かがファイルを開くことができなくなる可能性があります。たとえば、権限を変更したり、削除したりできます。

2 つ目の問題は、スキャナーが閉じられていないため、コードがファイル記述子をリークする可能性があることです。特定のアプリケーション (書かれているとおり) では、スキャナーを使用した直後にアプリケーションを終了するため、これは問題ではありません。しかし、そうではなく、このコードが何度も呼び出された場合は、しばらくするとファイルを開くことができなくなることがあります。

これに対処する正しい方法は、次のようなコードを記述することです。

public static void main(String[] args) {
    try (Scanner input = openInput()) {
        while (input.hasNextLine()) {
            // do stuff
        }
    }
}

これは、Java 7 の新しい「try with resource」構文を使用して、try ステートメントの完了時にリソースが確実に閉じられるようにします。(Java 7 より前のバージョンでも try / finally を使用して同じことを行うことができますが、コードは少し面倒です。)

于 2012-12-02T07:48:41.117 に答える