目次
1. ストリームを閉じる必要があるのはなぜですか?
ネットワーク上の I/O ストリームやハードディスクなどの外部リソースに対する読み取りおよび書き込み操作が含まれる場合、使用後に閉じないとリソースの漏洩が発生し、ファイルのロックやその他の問題が発生する可能性があります。したがって、使用後はストリームを閉じる必要があります。
ストリームを閉じることはリソース解放メカニズムであり、リソースの長期占有を避けるために使用後にシステムのメモリ、CPU、またはネットワーク リソースを返すことを意味します。ストリームを閉じる一般的な方法は、close() メソッドを呼び出すことです。これにより、関連リソースが解放され、リソース リークを効果的に回避できます。
ストリームを閉じるタイミングは非常に重要で、ストリームを閉じるのが早すぎると通常の動作に影響を与える可能性があり、閉じるのが遅すぎるとリソース リークが発生する可能性があることに注意してください。実際の開発では、ストリームは使用後すぐに閉じる必要があります。Java 7 以降に構文が導入されtry-with-resources
、構文レベルでストリームを自動的に閉じることができます。
/* 读取文件 */
File file = new File("opsLiya.json");
try (FileInputStream fileInputStream = new FileInputStream(file)) {
/* 操作 */
}catch (IOException e){
/* 异常处理 */
}
もちろん、従来のfinallyブロックを使用してストリームを閉じることもできます。
InputStream inputStream = null;
try {
inputStream = new FileInputStream("opsLiya.txt");
/* 操作 */
} catch (IOException e) {
/* 异常处理 */
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
/* 异常处理 */
}
}
}
2. クローズ方法とフラッシュ方法
1. close メソッドを使用する
入力ストリームを使用するとき、たとえばFileInputStream
ストリームを閉じるとき、close メソッドを直接呼び出すことができます。
close メソッドの最下層は次のとおりです。
このclose0メソッドの最下層はネイティブメソッド(ローカルメソッド)です。
このメソッドは、特定のシャットダウン操作を実行します。
2. フラッシュ方式を使用する
出力ストリームを使用するとき(つまり、ファイルまたはネットワークにデータを書き込むとき)、たとえばBufferedOutputStream
ストリームを閉じるときは、最初にフラッシュ メソッドを呼び出し、次に close メソッドを呼び出す必要があります。
入力したBufferedOutputStream
フラッシュ メソッドのソース コードは次のとおりです。
メソッド アノテーションの一般的な意味は次のとおりです。刷新此缓冲输出流。这将强制将任何缓冲的输出字节写入底层输出流。
つまり、ストリームを閉じる前にフラッシュ メソッドを呼び出すと、データ損失を避けるためにキャッシュ内のデータが出力ターゲットに強制的に更新されます。
3. 方向による流れの分類
Java のストリームは、方向の観点から 2 つのカテゴリに分類できます。1 つはメモリの読み取りと書き込みに使用されるストリーム、もう 1 つは外部リソース (ファイル、ネットワークなど) の読み取りと書き込みに使用されるストリームです。
たとえば、メモリの読み書きに使用されるストリームは、操作対象に応じて次の 2 つのカテゴリに分類できます。
- 操作オブジェクトはバイト配列です。
- ByteArrayInputStream
- ByteArrayOutputStream
- 操作オブジェクトは文字列です。
- 文字列リーダー
- 文字列ライター
外部リソースの読み取りおよび書き込みに使用されるストリームには次のものがあります。
- FileInputStream および FileOutputStream: ファイルのバイト ストリームの読み取りおよび書き込みに使用されます。
- FileReader と FileWriter: ファイルの文字ストリームの読み取りと書き込みに使用されます。
- BufferedInputStream および BufferedOutputStream: IO パフォーマンスを向上させるために読み取りおよび書き込みバイト ストリームをキャッシュするために使用されます。
- BufferedReader および BufferedWriter: 読み取りおよび書き込み文字ストリームをキャッシュして IO パフォーマンスを向上させるために使用されます。
- DataInputStream および DataOutputStream: 整数や浮動小数点数などの基本型のバイト ストリームの読み取りおよび書き込みに使用できます。
- ObjectInputStream および ObjectOutputStream: Java オブジェクトの読み取りおよび書き込みに使用されるバイト ストリーム。
- ソケットとサーバーソケット: ネットワークデータ送信に使用されます。
- HttpURLConnection: HTTP リクエストなどに使用されます。
4. 閉じる必要のないストリーム
ByteArrayInputStream
JavaおよびJava ではByteArrayOutputStream
、それらはすべてメモリ内で読み取りおよび書き込み操作を実行し、基礎となる外部リソース (ファイル、ネットワークなど) を関与させる必要がないため、使用後に閉じるために close メソッドを明示的に呼び出す必要は必ずしもありません。 . . それらが占有するメモリは、JVM によって自動的に再利用されます。次のように、 close メソッドの実装は
空のメソッドです。ByteArrayInputStream
もちろん、try-with-resources
次の構文を使用して、占有しているメモリを手動で解放することもできます。
byte[] data = new byte[]{
1, 2, 3, 4, 5};
try (ByteArrayInputStream bis = new ByteArrayInputStream(data);
ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
/* 操作 */
} catch (IOException e) {
/* 异常处理 */
}
注: その close メソッドは空の実装ですが、コードの可読性と堅牢性を確保するために、使用後も時間内にメソッドを閉じる必要があります。