文字入力ストリーム
日本語 | 文字入力流れ |
英語 | character-input stream |
ふりがな | もじにゅうりょくすとりーむ |
フリガナ | モジニュウリョクストリーム |
ストリームの一種。
文字ストリームの一種で、入力を行う。
バイトストリームと異なり、文字を取得するために使用する。
また、文字出力ストリームと異なり、出力ではなく入力を行うために使用する。
具体的には、Readerクラス及びそのサブクラスを指す。
J2SEの以下のクラスが該当する。
・Reader
・CharArrayReader
・StringReader
・FileReader
・PipedReader
・FilterReader
・BufferedReader
・LineNumberReader
・PushbackReader
・InputStreamReader
役割で分けると以下のようになる。
■スーパークラス
・Reader
■入力元
・CharArrayReader
・StringReader
・FileReader
・PipedReader
・InputStreamReader
■中継ぎ
・FilterReader
・BufferedReader
・LineNumberReader
・PushbackReader
・InputStreamReader
■取得用
・BufferedReader
・LineNumberReader
「文字」をストリームから取得するためのクラス。
まず、対象とするストリームを元に、「入力元」クラスを決定する。
文字列や文字列配列を対象とするならCharArrayReaderクラスやStringReaderクラスを使用する。
ファイルを対象とするならFileReaderクラスを使用する。
PipedWriterクラスを対象とするならPipedReaderクラスを使用する。
また、入力元がバイト入力ストリームクラスの場合、InputStreamReaderクラスを使用する。
これらのクラスのコンストラクタで「本当の入力元」を指定することで接続する。
入力元クラスがあれば、基本的にはストリームから文字及び文字列を取得することができる。
read()メソッドで文字及び文字列を取得する。
引数を持たないread()メソッドは1文字ずつ取得する。戻り値の型はint型だが、返される値の範囲はchar型、つまり0x00000000~0x0000FFFFである。また、read()メソッド呼び出し時に「それ以上取得できない場合」、つまりストリームの末端にある場合には-1が返される。
引数が(char[], int, int)のread()メソッドは、第1引数の、第2引数の位置から第3引数の要素数分の範囲に文字列をコピーする。つまり引数経由で複数の文字を返す。戻り値には実際に第1引数にセットした文字数を返す。「それ以上取得できない場合」には-1を返す。
「入力元」クラスだけでは不便な場合は、「中継ぎ」となるクラスを使用する。
「バッファリング」、つまりストリームから文字列をまとめて取得する場合にはBufferedReaderクラスを使用する。
入力ストリームの行数を取得したい場合にはLineNumberReaderクラスを使用する。
取得時に他の文字列を挟み込めるようにする場合にはPushbackReaderクラスを使用する。
これら、「中継ぎ」クラスはコンストラクタにReaderクラスのサブクラスを渡すことができるため、コンストラクタに入力元クラスや他の中継ぎクラスを渡すことで、「入力元←中継ぎ←中継ぎ」のようにチェーン化することができる。
チェーン化すると、入力元の方向へとバケツリレーのようにread()メソッドを呼び出し、結果を呼び出し元へと返す。その呼び出しの間に、中継ぎクラスはバッファリング等の処理を行う。
さらに、文字列取得を容易にする場合には「取得用」のクラスを使用する。
取得用クラスは、文字列を取得する場合に「便利なメソッド」を提供する。read()メソッドは、1文字ずつ、もしくはchar型の配列としてしか返さないため、read()メソッドによる取得は面倒である。
そのため、取得に便利なメソッドを持つ取得用クラスを入力元クラスや中継ぎクラスに接続し、取得用クラスのメソッドを呼ぶようにする。
文字入力ストリームクラスには取得専用のクラスは存在しない。バイト入力ストリームクラスのDataInputStreamクラスのようなクラスが文字入力ストリームクラスに存在しないのは、文字列として取得してしまえば、それをどう変換するかは変換する側の問題だからである。
文字入力ストリームクラスには、中継ぎ用クラスであるBufferedReaderクラスやそのサブクラスであるLineNumberReaderクラスが、取得用クラスとしても使用することができる。
BufferedReaderクラスのreadLine()メソッドは文字入力ストリームから文字列を一行単位で取得することができる。戻り値はStringクラスのため、簡単に取得することができる。
BufferedReaderクラスはバッファリングを行うため、入力の高速化を行うことができる。その中継ぎクラスとしてのメリットと取得用クラスとしてのメリットの併せ持つため、BufferedReaderクラスは便利なクラスと言える。
終了時には、close()メソッドを呼び出す。
入力元のストリームがファイルやソケットである場合、処理後は必ずclose()メソッドを呼び終了処理を行う必要がある。そのため、close()メソッドはfinallyブロック内で行うようにする。
念のため、文字列を扱う入力元クラスや、中継ぎクラス、取得用クラスのclose()メソッドも呼び出す。これは多くの場合必要はないが、呼んでおいた方が精神的にいいだろう。
中継ぎクラス、取得用クラスのclose()メソッドを呼び出すと、ほとんどのクラスはコンストラクタで渡された入力元クラスや中継ぎクラス、つまり「チェーンで連結している先」のclose()メソッドも呼び出すため、本当はチェーンの「実際に使用する側」、つまり取得用クラスか、取得用クラスがなければ中継ぎクラスのclose()メソッドを呼び出せば、接続先の文字入力ストリームクラスのclose()メソッドも呼び出してくれるが、仕様上必ずしもそうとは決められていないため、ひとつずつclose()メソッドを呼び出した方がいいだろう。
ストリームからの取得に失敗したとき等には、IOException例外が投げられる。
特にファイルやソケットが対象の場合、ケーブルが外された、等の外的要因によって取得に失敗する場合があるため、必ず例外の発生に対応する必要がある。
そのため、使用時にはtryブロックで囲み、IOExceptionクラスを拾うようにし、その後finallyブロックでclose()メソッドを呼び出すようにする。
ちなみに、このclose()メソッドもIOException例外を投げるため、これも拾うようにする。閉じる時に投げられる例外のため、行う処理は拾った際にはログの出力等を行うくらいでいいだろう。
このように、入力元クラス、中継ぎクラス、取得用クラスは「チェーン」で接続される。
「入力元クラス←中継ぎクラス←取得用クラス」とチェーン化する場合、まず入力元クラスのインスタンスを作成し、その参照を中継ぎクラスのインスタンス作成時のコンストラクタに渡し、その参照を取得用クラスのインスタンス作成時のコンストラクタに渡す。
このように「接続先の文字入力ストリームクラス」をコンストラクタで渡すことで、read()をメソッドを呼び出すと、接続先のread()メソッドが呼ばれる仕組みとなる。
一般的な使用方法としては、以下のようになる。
テキストファイルを開く場合には、入力元クラスにFileReaderクラス、中継ぎ兼取得用クラスにBufferedReaderクラスを使用する。ファイルからの入力はFileReaderクラスで行い、それをバッファリングしつつ一行ごとに取得するためBufferedReaderクラスを使用する。
ソケットから文字列を取得する場合には、ソケットから返されるInputStreamクラスをInputStreamReaderクラスに継なぎ、さらにBufferedReaderクラスを継なげるといいだろう。
それ以外の目的に使用することは少ない。文字入力ストリームのため、バイト入力ストリームに比べて対象が少ないこと、単に文字列変換したい場合等にはStringクラスやStringBufferクラスで十分なことが多いためである。
とりあえずは「テキストファイルから文字列を取得するために使う」程度でいいだろう。
文字ストリームの一種で、入力を行う。
バイトストリームと異なり、文字を取得するために使用する。
また、文字出力ストリームと異なり、出力ではなく入力を行うために使用する。
具体的には、Readerクラス及びそのサブクラスを指す。
J2SEの以下のクラスが該当する。
・Reader
・CharArrayReader
・StringReader
・FileReader
・PipedReader
・FilterReader
・BufferedReader
・LineNumberReader
・PushbackReader
・InputStreamReader
役割で分けると以下のようになる。
■スーパークラス
・Reader
■入力元
・CharArrayReader
・StringReader
・FileReader
・PipedReader
・InputStreamReader
■中継ぎ
・FilterReader
・BufferedReader
・LineNumberReader
・PushbackReader
・InputStreamReader
■取得用
・BufferedReader
・LineNumberReader
「文字」をストリームから取得するためのクラス。
まず、対象とするストリームを元に、「入力元」クラスを決定する。
文字列や文字列配列を対象とするならCharArrayReaderクラスやStringReaderクラスを使用する。
ファイルを対象とするならFileReaderクラスを使用する。
PipedWriterクラスを対象とするならPipedReaderクラスを使用する。
また、入力元がバイト入力ストリームクラスの場合、InputStreamReaderクラスを使用する。
これらのクラスのコンストラクタで「本当の入力元」を指定することで接続する。
入力元クラスがあれば、基本的にはストリームから文字及び文字列を取得することができる。
read()メソッドで文字及び文字列を取得する。
引数を持たないread()メソッドは1文字ずつ取得する。戻り値の型はint型だが、返される値の範囲はchar型、つまり0x00000000~0x0000FFFFである。また、read()メソッド呼び出し時に「それ以上取得できない場合」、つまりストリームの末端にある場合には-1が返される。
引数が(char[], int, int)のread()メソッドは、第1引数の、第2引数の位置から第3引数の要素数分の範囲に文字列をコピーする。つまり引数経由で複数の文字を返す。戻り値には実際に第1引数にセットした文字数を返す。「それ以上取得できない場合」には-1を返す。
「入力元」クラスだけでは不便な場合は、「中継ぎ」となるクラスを使用する。
「バッファリング」、つまりストリームから文字列をまとめて取得する場合にはBufferedReaderクラスを使用する。
入力ストリームの行数を取得したい場合にはLineNumberReaderクラスを使用する。
取得時に他の文字列を挟み込めるようにする場合にはPushbackReaderクラスを使用する。
これら、「中継ぎ」クラスはコンストラクタにReaderクラスのサブクラスを渡すことができるため、コンストラクタに入力元クラスや他の中継ぎクラスを渡すことで、「入力元←中継ぎ←中継ぎ」のようにチェーン化することができる。
チェーン化すると、入力元の方向へとバケツリレーのようにread()メソッドを呼び出し、結果を呼び出し元へと返す。その呼び出しの間に、中継ぎクラスはバッファリング等の処理を行う。
さらに、文字列取得を容易にする場合には「取得用」のクラスを使用する。
取得用クラスは、文字列を取得する場合に「便利なメソッド」を提供する。read()メソッドは、1文字ずつ、もしくはchar型の配列としてしか返さないため、read()メソッドによる取得は面倒である。
そのため、取得に便利なメソッドを持つ取得用クラスを入力元クラスや中継ぎクラスに接続し、取得用クラスのメソッドを呼ぶようにする。
文字入力ストリームクラスには取得専用のクラスは存在しない。バイト入力ストリームクラスのDataInputStreamクラスのようなクラスが文字入力ストリームクラスに存在しないのは、文字列として取得してしまえば、それをどう変換するかは変換する側の問題だからである。
文字入力ストリームクラスには、中継ぎ用クラスであるBufferedReaderクラスやそのサブクラスであるLineNumberReaderクラスが、取得用クラスとしても使用することができる。
BufferedReaderクラスのreadLine()メソッドは文字入力ストリームから文字列を一行単位で取得することができる。戻り値はStringクラスのため、簡単に取得することができる。
BufferedReaderクラスはバッファリングを行うため、入力の高速化を行うことができる。その中継ぎクラスとしてのメリットと取得用クラスとしてのメリットの併せ持つため、BufferedReaderクラスは便利なクラスと言える。
終了時には、close()メソッドを呼び出す。
入力元のストリームがファイルやソケットである場合、処理後は必ずclose()メソッドを呼び終了処理を行う必要がある。そのため、close()メソッドはfinallyブロック内で行うようにする。
念のため、文字列を扱う入力元クラスや、中継ぎクラス、取得用クラスのclose()メソッドも呼び出す。これは多くの場合必要はないが、呼んでおいた方が精神的にいいだろう。
中継ぎクラス、取得用クラスのclose()メソッドを呼び出すと、ほとんどのクラスはコンストラクタで渡された入力元クラスや中継ぎクラス、つまり「チェーンで連結している先」のclose()メソッドも呼び出すため、本当はチェーンの「実際に使用する側」、つまり取得用クラスか、取得用クラスがなければ中継ぎクラスのclose()メソッドを呼び出せば、接続先の文字入力ストリームクラスのclose()メソッドも呼び出してくれるが、仕様上必ずしもそうとは決められていないため、ひとつずつclose()メソッドを呼び出した方がいいだろう。
ストリームからの取得に失敗したとき等には、IOException例外が投げられる。
特にファイルやソケットが対象の場合、ケーブルが外された、等の外的要因によって取得に失敗する場合があるため、必ず例外の発生に対応する必要がある。
そのため、使用時にはtryブロックで囲み、IOExceptionクラスを拾うようにし、その後finallyブロックでclose()メソッドを呼び出すようにする。
ちなみに、このclose()メソッドもIOException例外を投げるため、これも拾うようにする。閉じる時に投げられる例外のため、行う処理は拾った際にはログの出力等を行うくらいでいいだろう。
このように、入力元クラス、中継ぎクラス、取得用クラスは「チェーン」で接続される。
「入力元クラス←中継ぎクラス←取得用クラス」とチェーン化する場合、まず入力元クラスのインスタンスを作成し、その参照を中継ぎクラスのインスタンス作成時のコンストラクタに渡し、その参照を取得用クラスのインスタンス作成時のコンストラクタに渡す。
このように「接続先の文字入力ストリームクラス」をコンストラクタで渡すことで、read()をメソッドを呼び出すと、接続先のread()メソッドが呼ばれる仕組みとなる。
一般的な使用方法としては、以下のようになる。
テキストファイルを開く場合には、入力元クラスにFileReaderクラス、中継ぎ兼取得用クラスにBufferedReaderクラスを使用する。ファイルからの入力はFileReaderクラスで行い、それをバッファリングしつつ一行ごとに取得するためBufferedReaderクラスを使用する。
ソケットから文字列を取得する場合には、ソケットから返されるInputStreamクラスをInputStreamReaderクラスに継なぎ、さらにBufferedReaderクラスを継なげるといいだろう。
それ以外の目的に使用することは少ない。文字入力ストリームのため、バイト入力ストリームに比べて対象が少ないこと、単に文字列変換したい場合等にはStringクラスやStringBufferクラスで十分なことが多いためである。
とりあえずは「テキストファイルから文字列を取得するために使う」程度でいいだろう。
// Sample.java
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Sample
{
public static void main( String[] args )
{
// 入力ファイルの絶対パス。
String inputFilePath = "D:/from.txt";
// このファイルには以下のように記述してください。
/*
あいう
えお
*/
// FileReaderクラスの参照型変数。
// ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
FileReader fileReader = null;
BufferedReader bufferedReader = null;
try
{
// まずFileReaderクラスを作ります。
// このクラス経由でファイルから文字列を取得します。
fileReader = new FileReader( inputFilePath );
// このクラスを対象とするBufferedReaderクラスを用意します。
bufferedReader = new BufferedReader( fileReader );
while( true )
{
// 一行取得します。
String line = bufferedReader.readLine();
if( line == null )
{
// nullが返されてきたら終わりです。
break;
}
// 出力します。
System.out.println( "(文頭)" + line +"(文末)" );
}
// (文頭)あいう(文末)
// (文頭)えお(文末)
// このように、BufferedReaderクラスのreadLine()メソッドなら
// OSに関係なく改行文字で分けて一行ずつ取得してくれます。
}
catch( IOException e )
{
// ファイルが無かった場合等に、この
// IOException例外が投げられます。
e.printStackTrace();
}
finally
{
// 処理が終わったら、最後にclose()メソッドを呼んで
// 後処理をします。また、これは必ず行うため、
// finally内で行います。
try
{
if( bufferedReader != null )
{
bufferedReader.close();
}
}
catch( IOException e )
{
// close()メソッドはIOExceptionがthrows指定されているので
// 一応受け取ります。
e.printStackTrace();
}
// ファイルを扱ったら、最後にclose()メソッドを呼んで
// 後処理をします。また、これは必ず行うため、
// finally内で行います。
try
{
if( fileReader != null )
{
fileReader.close();
}
}
catch( IOException e )
{
// close()メソッドはIOExceptionがthrows指定されているので
// 一応受け取ります。
e.printStackTrace();
}
}
}
}
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Sample
{
public static void main( String[] args )
{
// 入力ファイルの絶対パス。
String inputFilePath = "D:/from.txt";
// このファイルには以下のように記述してください。
/*
あいう
えお
*/
// FileReaderクラスの参照型変数。
// ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。
FileReader fileReader = null;
BufferedReader bufferedReader = null;
try
{
// まずFileReaderクラスを作ります。
// このクラス経由でファイルから文字列を取得します。
fileReader = new FileReader( inputFilePath );
// このクラスを対象とするBufferedReaderクラスを用意します。
bufferedReader = new BufferedReader( fileReader );
while( true )
{
// 一行取得します。
String line = bufferedReader.readLine();
if( line == null )
{
// nullが返されてきたら終わりです。
break;
}
// 出力します。
System.out.println( "(文頭)" + line +"(文末)" );
}
// (文頭)あいう(文末)
// (文頭)えお(文末)
// このように、BufferedReaderクラスのreadLine()メソッドなら
// OSに関係なく改行文字で分けて一行ずつ取得してくれます。
}
catch( IOException e )
{
// ファイルが無かった場合等に、この
// IOException例外が投げられます。
e.printStackTrace();
}
finally
{
// 処理が終わったら、最後にclose()メソッドを呼んで
// 後処理をします。また、これは必ず行うため、
// finally内で行います。
try
{
if( bufferedReader != null )
{
bufferedReader.close();
}
}
catch( IOException e )
{
// close()メソッドはIOExceptionがthrows指定されているので
// 一応受け取ります。
e.printStackTrace();
}
// ファイルを扱ったら、最後にclose()メソッドを呼んで
// 後処理をします。また、これは必ず行うため、
// finally内で行います。
try
{
if( fileReader != null )
{
fileReader.close();
}
}
catch( IOException e )
{
// close()メソッドはIOExceptionがthrows指定されているので
// 一応受け取ります。
e.printStackTrace();
}
}
}
}
// Sample.java import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; public class Sample { public static void main( String[] args ) { // 入力ファイルの絶対パス。 String inputFilePath = "D:/from.txt"; // このファイルには以下のように記述してください。 /* あいう えお */ // FileReaderクラスの参照型変数。 // ここで作っておくのはfinallyでclose()メソッドを呼ぶためです。 FileReader fileReader = null; BufferedReader bufferedReader = null; try { // まずFileReaderクラスを作ります。 // このクラス経由でファイルから文字列を取得します。 fileReader = new FileReader( inputFilePath ); // このクラスを対象とするBufferedReaderクラスを用意します。 bufferedReader = new BufferedReader( fileReader ); while( true ) { // 一行取得します。 String line = bufferedReader.readLine(); if( line == null ) { // nullが返されてきたら終わりです。 break; } // 出力します。 System.out.println( "(文頭)" + line +"(文末)" ); } // (文頭)あいう(文末) // (文頭)えお(文末) // このように、BufferedReaderクラスのreadLine()メソッドなら // OSに関係なく改行文字で分けて一行ずつ取得してくれます。 } catch( IOException e ) { // ファイルが無かった場合等に、この // IOException例外が投げられます。 e.printStackTrace(); } finally { // 処理が終わったら、最後にclose()メソッドを呼んで // 後処理をします。また、これは必ず行うため、 // finally内で行います。 try { if( bufferedReader != null ) { bufferedReader.close(); } } catch( IOException e ) { // close()メソッドはIOExceptionがthrows指定されているので // 一応受け取ります。 e.printStackTrace(); } // ファイルを扱ったら、最後にclose()メソッドを呼んで // 後処理をします。また、これは必ず行うため、 // finally内で行います。 try { if( fileReader != null ) { fileReader.close(); } } catch( IOException e ) { // close()メソッドはIOExceptionがthrows指定されているので // 一応受け取ります。 e.printStackTrace(); } } } }