InputStreamからデータを読み込む

Androidアプリでネットワークやファイルからデータを読み込むには、Javaに用意されているInputStreamを使用します。Android SDKがベースにしているJava2 SEには、データ入力の仕組みとしてInputStreamという基本的な入力用ストリームクラスがあり、ストリームの入力元としてネットワークやファイルを指定することが可能です。

今回は、このInputStreamを使ってデータの読込(byte配列への格納)を試してみます。

InputStreamは、ストリーム入力を行うクラスなので、基本的には「一つずつ(順番に)」データを読み込んでいきます。ただ、実際にInputStreamで読み込むデータソースはネットワークやファイルなどある程度「まとまったデータ」を取得できるはずです。バッファを確保して、そのバッファに読み込むことで効率化しましょう。

バッファの大きさは、ストリームから一度に読み込む(最大の)データ量になります。どれだけの大きさを確保するのが良いのか、悩みどころですね。とりあえず今回は1024バイトにしてみましたが、最近のAndroid端末は無線通信も高速ですから、もっと大きくても良いかもしれません。

バッファを確保したら、そのバッファをInputStreamのread()メソッドに渡して、ストリームからデータを読み込みます。read()は、読み込まれたデータ数を返すので、1以上の値が返される間、読み込みを続けましょう。

読み込んだデータは、順次ByteArrayOutputStreamに格納して行きます。ByteArrayOutputStreamは、write()でデータを追加していくと自動的にデータ領域が拡大されるので、便利ですね。

以下は、InputStreamを渡すと読み込めるだけデータを読み込み(ファイルならファイル全体)、読み込んだデータをbyte型配列として返す関数です。

byte[] readStream(InputStream is) {

	byte[] buf = new byte[1024];

	ByteArrayOutputStream bos = new ByteArrayOutputStream();

	int load = 0;
	int pos = 0;

	try {
		do {

			load = is.read(buf);

			if (load > 0) {

				bos.write(buf, 0, load);
				pos += load;

			}

		} while (load > 0);
	} catch (Exception e) {
		pos = -1;
	} finally {
		try {
			is.close();
		} catch (Exception e) {
		}
	}

	if (pos == -1) {
		return null;
	}

	return bos.toByteArray();

}

Androidでは、ファイルやネットワークなど入出力が可能な経路にはストリーム(入力用のInputStreamや出力用のOutputStream)を取得する仕組みが用意されています。たとえば、ファイルオブジェクトfileからデータを読み込むには、まず

InputStream is = new FileInputStream(file);

のようにしてストリームを作成します。