14

基本的には、ファイルを開いて、いくつかのバイトを読み取ってから、ファイルを閉じます。これは私が思いついたものです:

try
{
    InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
    try
    {
        // ...
        inputStream.read(buffer);
        // ...
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally
    {
        try
        {
            inputStream.close();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
catch (FileNotFoundException e)
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}

たぶん私はRAIIに甘やかされていますが、Javaでこれを行うためのより良い方法があるはずですよね?

4

9 に答える 9

12

IOExceptionと同じ例外処理コードがある場合は、次の1つの句FileNotFoundExceptionだけで、よりコンパクトな方法で例を書き直すことができます。catch

try {
    InputStream input = new BufferedInputStream(new FileInputStream(file));
    try {
        // ...
        input.read(buffer);
        // ...
    }
    finally {
        input.close();
    }
}
catch (IOException e) {
    e.printStackTrace();
}

try-catchスタックトレースを手動で出力するよりもおそらく理にかなっている例外を伝播できる場合は、外部を取り除くこともできます。プログラムで例外が発生しない場合は、スタックトレースが自動的に出力されます。

また、ストリームを手動で閉じる必要性は、自動リソース管理を備えたJava7で対処されます。

自動リソース管理と例外伝播により、コードは次のように削減されます。

try (InputStream input = new BufferedInputStream(new FileInputStream(file))) {
    // ...
    input.read(buffer);
    // ...
}
于 2011-06-06T09:54:41.233 に答える
2

通常、これらのメソッドはライブラリにラップされています。このレベルで記述したい場合を除いて、独自のヘルパーメソッドを作成するか、 FileUtilsなどの既存のメソッドを使用することをお勧めします。

String fileAsString = Fileutils.readFileToString(filename);
// OR
for(String line: FileUtils.readLines(filename)) {
    // do something with each line.
}
于 2011-06-06T10:03:24.523 に答える
1

それが正しい方法かどうかはわかりませんが、すべてのコードを同じtryブロックに入れてから、異なるcatchブロックを次々に配置することができます。

try {
  ...
}
catch (SomeException e) {
  ...
}
catch (OtherException e) {
  ...
}
于 2011-06-06T09:51:17.920 に答える
1

プレーンJavaでこれを実行したい場合は、投稿したコードは問題ないように見えます。

Commons IOなどのサードパーティライブラリを使用できます。このライブラリでは、はるかに少ないコードを記述する必要があります。例えば

CommonsIOをチェックしてください:

http://commons.apache.org/io/description.html

于 2011-06-06T09:54:19.403 に答える
1

コードを次のように減らすことができる場合があります。

public void foo(String name) throws IOException {
    InputStream in = null;
    try {
        in = new FileInputStream(name);
        in.read();
        // whatever
    } finally {
        if(in != null) {
            in.close();
        }
    }
}

もちろん、これはの呼び出し元がfoo処理する必要があることを意味しIOExceptionますが、とにかくほとんどの場合これが当てはまるはずです。結局、それほど複雑さを軽減することはできませんが、ネストされた例外ハンドラーが少なくなるため、コードははるかに読みやすくなります。

于 2011-06-06T11:43:25.887 に答える
1

ユーティリティを使用せずにこれを行うと、次のようになります。

InputStream inputStream = null;
try {
    inputStream = new BufferedInputStream(new FileInputStream(file));
    // ...
    inputStream.read(buffer);
    // ...
} catch (IOException e) {
    e.printStackTrace();
    throw e; // Rethrow if you cannot handle the exception
} finally {
    if (inputStream != null) {
        inputStream.close();
    }
}

ワンライナーではありませんが、それほど悪くはありません。たとえば、Apache Commons IOを使用すると、次のようになります。

//...
buffer = FileUtils.readFileToByteArray(file);
//...

覚えておくべきことは、標準のJavaには、誰もが必要とするこれらの小さなユーティリティや使いやすいインターフェイスの多くが欠けているため、プロジェクトでApache CommonsGoogle Guava、...などのサポートライブラリに依存する必要があることです(または独自のユーティリティクラス)。

于 2011-06-06T13:21:28.310 に答える
0

Google guavaは、 Closeablesを導入することでこの問題に対処しようとしました。

それ以外の場合は、IOExceptionがスローされた場合のいくつかに対処するため、JDK7のAutoCloseableが出るまで待つ必要があります。

于 2011-06-06T10:00:36.473 に答える
0

org.apache.commons.io.FileUtils.readFileToByteArray(File)そのパッケージからまたは類似のものを使用してください。それでもIOExceptionをスローしますが、クリーンアップを処理します。

于 2011-06-06T09:54:59.997 に答える
0

次のことを試してください。

try
{
    InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
    byte[] buffer = new byte[1024];
    try
    {
        // ...
        int bytesRead = 0;
        while ((bytesRead = inputStream.read(buffer)) != -1) {                
           //Process the chunk of bytes read
        }
    }
    catch (IOException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally
    {           
        inputStream.close();
    }
}
catch (FileNotFoundException e)
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}
于 2011-06-06T09:57:00.150 に答える