Java I/O完全ガイド: ファイル・ストリーム・標準入出力の基礎
java.ioパッケージには、Javaで入出力(I/O)を実行するために必要なほぼすべてのクラスが含まれています。これらのストリームはすべて入力ソースと出力先を表します。java.ioパッケージのストリームは、プリミティブ型、オブジェクト、ローカライズされた文字など、多くの種類のデータをサポートしています。
ストリーム
ストリームとはデータのシーケンスと定義できます。ストリームには2種類あります。
- InputStream - ソースからデータを読み取るために使用
- OutputStream - データをデスティネーションに書き込むために使用
Javaはファイルおよびネットワークに関連するI/Oに対して強力かつ柔軟なサポートを提供しますが、このチュートリアルではストリームとI/Oに関する非常に基本的な機能のみを扱います。最も一般的に使用される例を順に見ていきます。
バイトストリーム
Javaバイトストリームは8ビットバイトの入出力を実行するために使用されます。バイトストリームに関連するクラスは多数ありますが、最も頻繁に使用されるのはFileInputStreamとFileOutputStreamです。以下はこれら2つのクラスを使用して入力ファイルを出力ファイルにコピーする例です。
例
import java.io.*;
public class CopyFile {
public static void main(String args[]) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("input.txt");
out = new FileOutputStream("output.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
以下の内容を持つinput.txtファイルがあるとします。
This is test for copy file.
上記プログラムをコンパイルして実行すると、input.txtと同じ内容のoutput.txtファイルが作成されます。
$ javac CopyFile.java
$ java CopyFile
文字ストリーム
Javaバイトストリームが8ビットバイトの入出力に使用されるのに対し、Java文字ストリームは16ビットUnicodeの入出力に使用されます。文字ストリームに関連するクラスも多数ありますが、最も頻繁に使用されるのはFileReaderとFileWriterです。内部的にはFileReaderはFileInputStreamを、FileWriterはFileOutputStreamを使用しますが、大きな違いはFileReaderが一度に2バイト読み、FileWriterが一度に2バイト書き込む点です。
上記の例をこれら2つのクラスを使用して書き換えると、Unicode文字を持つ入力ファイルを出力ファイルにコピーできます。
例
import java.io.*;
public class CopyFile {
public static void main(String args[]) throws IOException {
FileReader in = null;
FileWriter out = null;
try {
in = new FileReader("input.txt");
out = new FileWriter("output.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
標準ストリーム
すべてのプログラミング言語は標準I/Oをサポートしており、ユーザープログラムはキーボードから入力を受け取り、コンピュータ画面に出力を生成できます。CやC++をご存知なら、STDIN、STDOUT、STDERRという3つの標準デバイスをご存知でしょう。同様にJavaは以下の3つの標準ストリームを提供します。
- 標準入力 - ユーザープログラムにデータを供給するために使用。通常キーボードが標準入力ストリームとして使用され、
System.inで表される。 - 標準出力 - ユーザープログラムが生成したデータを出力するために使用。通常コンピュータ画面が標準出力ストリームとして使用され、
System.outで表される。 - 標準エラー - ユーザープログラムが生成したエラーデータを出力するために使用。通常コンピュータ画面が標準エラーストリームとして使用され、
System.errで表される。
例: 標準入力から読み取り
ユーザーが「q」を入力するまで標準入力ストリームを読み取るInputStreamReaderを作成するシンプルなプログラムです。
import java.io.*;
public class ReadConsole {
public static void main(String args[]) throws IOException {
InputStreamReader cin = null;
try {
cin = new InputStreamReader(System.in);
System.out.println("Enter characters, 'q' to quit.");
char c;
do {
c = (char) cin.read();
System.out.print(c);
} while (c != 'q');
} finally {
if (cin != null) {
cin.close();
}
}
}
}
上記コードをReadConsole.javaに保存し、コンパイル・実行すると、'q'が押されるまで同じ文字を読み取って出力し続けます。
$ javac ReadConsole.java
$ java ReadConsole
Enter characters, 'q' to quit.
1 1 e e q q
ファイルの読み書き
前述の通り、ストリームはデータのシーケンスと定義できます。InputStreamはソースからデータを読み取るために使用し、OutputStreamはデータをデスティネーションに書き込むために使用します。
入力ストリームと出力ストリームを扱うクラス階層があります。重要な2つのストリームはFileInputStreamとFileOutputStreamです。
FileInputStream
このストリームはファイルからデータを読み取るために使用します。newキーワードを使用してオブジェクトを作成でき、いくつかのタイプのコンストラクタが利用可能です。
以下のコンストラクタはファイル名を文字列として受け取り、ファイルを読み取るための入力ストリームオブジェクトを作成します。
InputStream f = new FileInputStream("C:/java/hello");
以下のコンストラクタはファイルオブジェクトを受け取り、ファイルを読み取るための入力ストリームオブジェクトを作成します。まずFile()メソッドを使用してファイルオブジェクトを作成します。
File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);
InputStreamオブジェクトを取得したら、ストリームを読み取ったり他の操作を行ったりするためのヘルパーメソッドのリストがあります。
| No. | メソッドと説明 |
|---|---|
| 1 | public void close() throws IOException - ファイル出力ストリームを閉じる。ファイルに関連付けられたシステムリソースを解放。IOExceptionをスロー。 |
| 2 | protected void finalize() throws IOException - ファイルへの接続をクリーンアップ。このファイル出力ストリームのcloseメソッドが、このストリームへの参照がなくなったときに呼び出されることを保証。IOExceptionをスロー。 |
| 3 | public int read(int r) throws IOException - InputStreamから指定バイトのデータを読み取る。intを返す。次のデータバイトを返し、ファイル末尾なら-1を返す。 |
| 4 | public int read(byte[] r) throws IOException - 入力ストリームからr.lengthバイトを配列に読み取る。読み取った総バイト数を返す。ファイル末尾なら-1を返す。 |
| 5 | public int available() throws IOException - このファイル入力ストリームから読み取れるバイト数を返す。intを返す。 |
他にも重要な入力ストリームがあります。詳細は以下を参照してください。
- ByteArrayInputStream
- DataInputStream
FileOutputStream
FileOutputStreamはファイルを作成し、データを書き込むために使用します。ファイルが存在しない場合は、出力用に開く前にファイルを作成します。
FileOutputStreamオブジェクトを作成するための2つのコンストラクタがあります。
ファイル名を文字列として受け取り、ファイルを書き込むための出力ストリームオブジェクトを作成します。
OutputStream f = new FileOutputStream("C:/java/hello")
ファイルオブジェクトを受け取り、ファイルを書き込むための出力ストリームオブジェクトを作成します。まずFile()メソッドでファイルオブジェクトを作成します。
File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);
OutputStreamオブジェクトを取得したら、ストリームに書き込んだり他の操作を行ったりするためのヘルパーメソッドのリストがあります。
| No. | メソッドと説明 |
|---|---|
| 1 | public void close() throws IOException - ファイル出力ストリームを閉じる。ファイルに関連付けられたシステムリソースを解放。IOExceptionをスロー。 |
| 2 | protected void finalize() throws IOException - ファイルへの接続をクリーンアップ。このファイル出力ストリームのcloseメソッドが、このストリームへの参照がなくなったときに呼び出されることを保証。IOExceptionをスロー。 |
| 3 | public void write(int w) throws IOException - 指定バイトを出力ストリームに書き込む。 |
| 4 | public void write(byte[] w) - 指定バイト配列からw.lengthバイトをOutputStreamに書き込む。 |
他にも重要な出力ストリームがあります。詳細は以下を参照してください。
- ByteArrayOutputStream
- DataOutputStream
例: InputStreamとOutputStreamのデモ
import java.io.*;
public class FileStreamTest {
public static void main(String args[]) {
try {
byte bWrite[] = {11, 21, 3, 40, 5};
OutputStream os = new FileOutputStream("test.txt");
for (int x = 0; x < bWrite.length; x++) {
os.write(bWrite[x]); // バイトを書き込み
}
os.close();
InputStream is = new FileInputStream("test.txt");
int size = is.available();
for (int i = 0; i < size; i++) {
System.out.print((char) is.read() + " ");
}
is.close();
} catch (IOException e) {
System.out.print("Exception");
}
}
}
上記コードはtest.txtファイルを作成し、指定された数値をバイナリ形式で書き込みます。同じ内容が標準出力にも表示されます。
ファイルナビゲーションとI/O
ファイルナビゲーションとI/Oの基礎を知るために、以下のクラスを見ていきます。
- Fileクラス
- FileReaderクラス
- FileWriterクラス
Javaでのディレクトリ操作
ディレクトリは、他のファイルやディレクトリのリストを含むFileです。Fileオブジェクトを使用してディレクトリを作成したり、ディレクトリ内の利用可能なファイルをリストアップしたりします。完全な詳細については、Fileオブジェクトで呼び出せるすべてのメソッドのリストと、ディレクトリに関連するものを確認してください。
ディレクトリの作成
ディレクトリを作成するための便利なFileユーティリティメソッドが2つあります。
mkdir()メソッドはディレクトリを作成し、成功時はtrue、失敗時はfalseを返す。失敗は、Fileオブジェクトで指定されたパスが既に存在するか、パス全体がまだ存在しないためにディレクトリを作成できないことを示す。mkdirs()メソッドはディレクトリとそのすべての親ディレクトリを作成する。
例: "/tmp/user/java/bin"ディレクトリの作成
import java.io.File;
public class CreateDir {
public static void main(String args[]) {
String dirname = "/tmp/user/java/bin";
File d = new File(dirname);
// ディレクトリを作成
d.mkdirs();
}
}
上記コードをコンパイルして実行すると/tmp/user/java/binが作成されます。
注意 - JavaはUNIXとWindowsの規約に従ってパス区切り文字を自動的に処理します。Windows版Javaでスラッシュ(/)を使用しても、パスは正しく解決されます。
ディレクトリのリスト表示
Fileオブジェクトのlist()メソッドを使用して、ディレクトリ内のすべてのファイルとディレクトリをリストアップできます。
例
import java.io.File;
public class ReadDir {
public static void main(String[] args) {
File file = null;
String[] paths;
try {
// 新しいファイルオブジェクトを作成
file = new File("/tmp");
// ファイルとディレクトリパスの配列
paths = file.list();
// パス配列の各名前に対して
for (String path : paths) {
// ファイル名とディレクトリ名を表示
System.out.println(path);
}
} catch (Exception e) {
// エラーが発生した場合
e.printStackTrace();
}
}
}
これはお使いの/tmpディレクトリで利用可能なディレクトリとファイルに基づいて以下のような結果を生成します。
実行結果(例)
test1.txt
test2.txt
ReadDir.java
ReadDir.class
Java
- C言語入出力(I/O)マスター:scanf()とprintf()徹底解説
- PythonファイルI/O:ファイル操作、読み書き、管理のマスター
- Java変数とリテラル:包括的ガイド
- Java入出力をマスター:表示、読み取り、データフォーマット
- Javaクラスとオブジェクト:実践ガイド
- Java抽象クラスとメソッド:包括的ガイド
- Javaネストクラスとインナークラス完全ガイド:種類、例、ベストプラクティス
- Java throw vs throws:実践例でマスターする例外ハンドリング
- Java Scanner完全ガイド:実践例で学ぶ入力処理
- Javaオートボクシングとアンボクシング完全ガイド:実例とベストプラクティス
- Javaオブジェクトとクラス:コアOOP概念を完全理解