I/OストリームはJavaの基本的な概念の一つで、言語の初期バージョンから存在しています。この概念は、データの読み書きプロセスを抽象化する目的で元々設計されました。ストリームはファイル、ネットワーク、あるいはコンソールと結び付けることができ、コードにとっては同じに見えます。
問題は、開発者がストリームを正しく管理せず、閉じるのを忘れたり、異なるタイプのストリーム(キャラクターとバイト)を混同したりすることで発生し、これによりリソースのリーク、データの歪み、または実行時エラーにつながることがよくあります。
解決策は、I/Oストリーム(InputStream/OutputStreamはバイト、Reader/Writerはキャラクター)の階層を正確に理解し、作業が完了した後に必ずストリームを閉じることで、Java 7以降はtry-with-resourcesを使用することです。
ファイルの読み書きのためのコード例:
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt")); BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); } }
主な特徴:
JavaでI/Oストリームを閉じないとどうなりますか?
ストリームはOSの低レベルのリソースを扱っており、ストリームを閉じないとメモリリーク、ファイルのロック、アプリケーションの障害、またはOSレベルでのファイルデスクリプタの枯渇につながる可能性があります。
同じOutputStreamを使って異なるファイルに書き込むことはできますか?
いいえ、従来のOutputStreamは一つのデータソース/シンクと強く関連付けられています。異なるファイルには異なるOutputStreamオブジェクトが必要です。
PrintWriterとBufferedWriterの違いは何ですか?どのように使い分けますか?
PrintWriterは形式化された出力メソッド(例: println())で出力を補完することに特化しており、自動フラッシュ機能があります。一方、BufferedWriterは主にバッファリングによってパフォーマンスを向上させます。ほとんどのアプリケーションでは、PrintWriterがテキスト出力に推奨されますが、形式化なしで迅速に文字や文字列を書き込む必要がある場合はBufferedWriterが適しています。
開発者がFileInputStreamを使用して大きなファイルからデータを読み取るが、バッファリングを使用せず、ストリームを閉じるのを忘れる。
長所:
短所:
BufferedReaderとtry-with-resourcesの組み合わせを使用し、文字列単位でパッケージとして読み取りと処理を行い、ストリームが自動的に閉じる。
長所:
短所: