Java -入出力の種類-
ストリームには入力用と出力用があります。
さらに1バイトずつデータをやり取りする
バイトストリーム、 1文字(2バイト)ずつデータをやり取りする
キャラクタストリーム にわけることができます。
また、バイトストリームやキャラクタストリームを拡張し、int型データ(4バイト)を入出力できる ストリームや1行単位の入出力を可能とするバッファリング機能を持つストリームもあります。
java.ioパッケージには、これらのような機能の異なる様々なストリームに対応したクラスが容易されており、 これらを組み合わせて利用することができます。
行単位の読み込み(BufferedReader)
ファイルから読み込みを1行単位で行いたい場合BufferedReaderクラスを利用します。
BufferedReaderは、ファイル名を表すStringやFileオブジェクトを直接引数にして生成することができません。
まず、ファイルへのキャラクタストリームであるFileReaderオブジェクトを生成し、そのストリーム(FileReaderオブジェクト) を引数にしてBufferedReaderオブジェクトを生成します。
- BufferedReaderクラスのコンストラクタ
-
- BufferedReader(Reader in)
- BufferedReader(Reader in, int sz)
引数szには、バッファのサイズを指定できます。
FileReaderオブジェクトは、ハードディスク上に存在するファイルに対するストリームを表します。
BufferedReaderオブジェクトは、別のストリームに対して読み込みを行うストリームです。
読み込み先は、ファイルとは限りません。引数に指定するストリームが同一コンピュータ上の プログラムやネットワーク上のプログラムに対するストリームでも構いません。
ストリームは、データの道であり、その先がファイルとは限りません。
ストリームにBufferedReaderを利用することでデータはバッファリングされ、1行単位で効率よく読み込むことができます。
サンプル
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReaderSample {
public static void main(String []args){
String path="./data/test.txt";
try {
BufferedReader in=new BufferedReader(new FileReader(path));
String line;
while((line=in.readLine())!=null){
System.out.println(line);
}
in.close();
}catch(FileNotFoundException e){
e.printStackTrace();
} catch(IOException e){
e.printStackTrace();
}
}
}
BufferedReaderは、Readerクラスを継承しているため、1文字ずつ読み込むreadメソッドも利用できますが、 効率よく1行ずつ読み込むための readLineメソッドが容易されています。
String readLine() throws IOException
readLineメソッドは、読み込んだ1行をStringとして返します。
ただし行の終端文字(改行コード)は含みません。
ストリームの終わりに達している場合はnullを返します。
BufferdReaderを利用すると、OSによる改行コードの違いを意識することなく、readLineメソッドで1行ずつ処理を行うことができます。
行単位の書き込み(BufferdWriter)
BufferdWriterクラスを利用して行単位の書き込みを行うことができます。
また、PringWriterクラスを利用しても行単位の書き込みが可能です。
- BufferedWriterクラスのコンストラクタ
-
- BufferedWriter(Writer out)
- BufferedWriter(Writer out,int sz)
- BufferedWriterクラスのwriteメソッド
-
- void write(int c)throws IOException
- void write(char[] cbuf,int off,int len) throws IOException
- void write(String s,int off, int len) throws IOException
lenのパラメータの値が負の場合は、文字は書き込まれません。
- Writeクラスから継承するwriteメソッド
-
- void write(char[] cbuf) throws IOException
- void write(String str) throws IOException
BufferdWriterクラスにはBufferedReaderクラスのreadLineのような改行コードを扱うメソッドはありません。
改行コードを書き込みたい場合は、newLineメソッドを呼び出すと、環境に応じた改行コードを追加することが できます。
行単位の書き込み(PrintWriter)
PrintWriterが、JDK5.0より拡張され、コンストラクタの引数にStringやFileを指定できるようになり、また formatメソッドやprintfメソッドが追加されてフォーマットされた出力も可能になりました。
- PrintWriterクラスのコンストラクタ
-
- PrintWriter(Writer out)
- PrintWriter(Writer out,boolean autoFlush)
- PrintWriter(OutputStream out)
- PrintWriter(OutputStream out,boolean autoFlush)
autoFlushがtrueの場合、printn,printf または、formatメソッドではバッファをフラッシュします。
- JDK5.0で追加されたコンストラクタ
-
- PrintWriter(String fileName) throws FileNotFoundException
- PrintWriter(String fileName,String csn) throws FileNotFoundException
csnには文字セット(charsetの名前)を指定できます。 - PrintWriter(File file) throws FileNotFoundException
- PrintWriter(File file,String csn) throws FileNotFoundException,UnsupportedEncodingException
サンプル
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class WriterSample {
public static void main(String[]args){
String path="./data/test.txt";
try {
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(path)));
out.println("foo");
out.println("bar");
out.close();
System.out.println("END");
} catch (IOException e) {
e.printStackTrace();
}
}
}
PrintWriterを利用すると、ファイル名をStringやFile型として直接指定することも可能です。
また、FileWriterを引数にして指定することもできます。
PrintWriterとBufferdWriterの違い
- PrintWriterはバッファリングしない
効率よく書き込みするにはBufferedWriterオブジェクトを引数に指定し、PrintWriterを生成する必要があります。 - PrintWriterのprintメソッドやprintlnメソッドは例外をスローしない。
書き込みに失敗したかどうかを確認するにはPrintWriterクラスのcheckErrorメソッドを呼び出して調べる必要があります。