3

(Java で) RandomAccessFile オブジェクトを作成し、書き込みと読み取りの両方を行いたいと考えています。私の問題は、私が知る限り、try/catch ブロック内でファイルを作成する必要があるように思われることです。try/catch ブロックの外側で作成してから、ブロック内で次のように初期化しようとすると、

RandomAccessFile valueFile; 

try
{
    valueFile = new RandomAccessFile("valuefile.txt", "rw");
    for (int i=0; i<numOfNums; i++)
        valueFile.writeDouble(randomizer.nextDouble()*200);
}
catch (Exception e)
{
    System.out.println("Couldn't find the values file.");
    System.exit(0);
}

for (int i=0; i<numOfNums; i++)
{
    double total = 0;
    valueFile.seek(0); // go to beginning of file to start reading it.
}

次に、「報告されていない例外 java.io.IOException; をキャッチするか、スローするように宣言する必要があります」というエラーが表示されます。(「変数 valueFile が初期化されていない可能性があります」というメッセージも表示されます。)

しかし、try/catch 内で作成すると、次のようになります

try
{
    RandomAccessFile valueFile = new RandomAccessFile("valuefile.txt", "rw");
    for (int i=0; i<numOfNums; i++)
        valueFile.writeDouble(randomizer.nextDouble()*200);
}
catch (Exception e)
{
    System.out.println("Couldn't find the values file.");
    System.exit(0);
}

for (int i=0; i<numOfNums; i++)
{
    double total = 0;
    valueFile.seek(0);
}

プログラムの後半で「シンボルが見つかりません:変数値ファイル」が表示されます。それは、valueFile が try/catch ブロックに対してローカルであると見なされているためだと思いますか? しかし、try/catch ブロックに対してローカルにならないように valueFile を作成するにはどうすればよいでしょうか。

4

4 に答える 4

6

あなたの最初のアプローチは正しかったと思います。エラーの原因はファイルの作成ではなく、valueFile.seek(0);呼び出しです。これも IO Exception をスローする可能性があるため、try/catch ブロックでも必要です。

編集: Jon が指摘したように、初期化されていない可能性があるため、コードはまだコンパイルされvalueFileません。に初期化するだけでnull動作します。

RandomAccessFile valueFile = null; 

代わりに、Jon's answer で説明されている方法の 1 つを使用して、コンパイラvalueFileが に到達するまでに実際に初期化されることを納得させることができvalueFile.seek(0)ます。彼の方法はより安全ですが、到達できないステートメントnullでコードを乱雑にする必要がないように、初期化するだけですぐに解決できます。throw

RandomAccessFileただし、宣言、新規での初期化、およびファイルへのすべてのアクセスを同じtryブロック内に移動するだけでよいと思います。それらを分割する正当な理由が思いつきません。

于 2012-09-11T01:02:13.247 に答える
5

最初のバージョンはほぼ正しいですが、2 つの問題があります。

  1. メソッドは をスローできると宣言していませんIOExceptionが、 を使用するとvalueFile.seek例外がスローされる可能性があります。メソッド宣言を変更するか、例外をキャッチして処理する必要があります。

  2. コンパイラは、それが決して正常に返らないことを知りませんSystem.exit(0)-それは通常の方法であると考えています。したがって、catch ブロックを次のようなもので終了するように変更する必要があります。

    return;
    

    また

    throw new AssertionError("We'll never get here.");
    

    valueFile その時点で、コンパイラは、try/catch ブロックを超えた場合、確実に割り当てられることを認識します。

ブロック内のすべてを移動すると、両方の問題が解消されることに注意catchてください。IOException

public void foo(int iterations) throws IOException {
    RandomAccessFile valueFile = new RandomAccessFile("valuefile.txt", "rw");
    for (int i = 0; i < iterations; i++) {
        valueFile.writeDouble(randomizer.nextDouble()*200);
    }

    for (int i = 0; i< iterations; i++) {
        double total = 0;
        valueFile.seek(0);
        // Presumably you'd read the contents here?
    }
}

...ただし、Java 7 を使用している場合は try-with-resources ステートメントを使用するか、それ以外の場合は単に try/finally ブロックを使用して、ファイルの処理が完了したらファイルを閉じる必要もあります。

于 2012-09-11T01:01:55.413 に答える
1
RandomAccessFile valueFile; 

する必要があります:

RandomAccessFile valueFile = null; 

(「変数 valueFile が初期化されていない可能性があります」というメッセージも表示されます。)

上記を修正します。

于 2012-09-11T01:29:38.983 に答える
0

try catch ブロックの外側で変数を宣言し、その中からロードします。

RandomAccessFile valueFile;

try
{
    valueFile = new RandomAccessFile("valuefile.txt", "rw");
    for (int i=0; i<numOfNums; i++)
        valueFile.writeDouble(randomizer.nextDouble()*200);
}
于 2012-09-11T01:02:15.280 に答える