次のプログラムを見てください。このプログラムも、URLで指定された内容を表示する
ものです。今回、一番最初に見た、UrlStream.java と、ほとんど違いがありません。
URLから直接 InputStream を、openStream()で作っています。
(main を省略しています。)
この例で見て欲しいのは、次のようにして新しいOutput クラスである、 ByteArrayOutputStream のインスタンスが生成されていることです。
ByteArrayOutputStream out = new ByteArrayOutputStream();
ストリームさえ出来てしまえば、後の処理は、同じようなものです。 入力ストリームから読み込んだ情報を出力ストリームに書き出すだけです。
while((n = in.read(buf, 0, buf.length)) != -1){
out.write(buf,0,n);
}
何か、入力ストリームから読み込んだ情報を、バッファ buf に書いているかの
ように読んでしまう人がいるかも知れませんが、そうではありません。
buf に入力ストリームから読み込まれた情報を、outに書いているのです。
ところで、このoutは、いままでのファイルやソケットを実体とするストリームとは
ちょっと違っています。その実体は、その名前のように、メモリー上の
ByteArray(バイトの配列)なのです。
Javaには、ポインタという概念がありませんし、Cの様に、malloc()でメモリー上の
領域を自分で割り当てるということも行いません。ですから、outの実体がメモリー
であることは分かりますが、どの番地のメモリーなのかは全然わかりません。
Javaは、むしろこうしたことの管理からプログラマを解放しようという思想を
明確に持って設計された言語です。もっとも、それは、プログラマをメモリー管理の
苦痛から解放するというよりは、プログラムをプログラマの過ちから解放することを
狙っているのは知っておいた方がいいかもしれません。
所で、このバイトアレー出力ストリームでは、
System.out.println(out.toString());
という部分に注意してください。while ループの中で、outにためこまれた情報は、
ここで、一気に、String に変換されて、標準出力への出力が行われることに
なります。
サンプルは割愛しますが、任意のバイトアレー上の情報は、ByteArrayInputStream として、入力の対象にすることが出来ます。ByteArrayOutputStreamと組み合わせれば、 今までは、ポインタを操作して、直接、メモリーの内容を読み書きするしかなかった プログラムを、使い慣れた入出力プログラムの形で書けるということで、これも、 なかなか便利な機能です。また、入出力のプログラムで、テンポラリー・ファイルへの 読み書きが必要な処理は、バイトアレーの入出力ストリームを使うと高速化 出来るわけです。
****************************
** ByteStream.java
****************************
1 import java.net.*;
2 import java.io.*;
3
4 class ByteStream {
5
6 ByteStream(String src){
7 try {
8
9 URL u = new URL( src );
10 InputStream in = u.openStream() ;
11 byte buf[] = new byte[256];
12 ByteArrayOutputStream out = new ByteArrayOutputStream();
13 int n;
14
15 while((n = in.read(buf, 0, buf.length)) != -1){
16 out.write(buf,0,n);
17 }
18 System.out.println(out.toString());
19
20 } catch (Exception e){
21 System.err.println("Exception : "+e);
22 }
23 }
24 }