#author("2019-11-28T15:44:45+09:00","ocha","ocha")
#author("2019-11-28T15:46:57+09:00","ocha","ocha")
[[Lecture]]

*Java プログラミング入門 [#de53d4fb]


このページは、学部2年生向け授業である、「マルチメディアプログラミング実習」
のために用意しました。

(Wikiの仕様で大文字小文字が混在した英単語に疑問符?が追加されるところがありますが、無視してください。)


**第9章 エラーと例外処理 [#gd4f8eae]


C言語では、エラーが出そうな処理をする場合は、エラーが発生するかどうかをステップごとにif文でチェックして、対処していました。プログラムが読みにくく煩雑になりがちです。

現代的な言語では、プログラムの処理をブロックでまとめて、その部分から発生したエラーを別の部分で受け取って処理をする書き方ができます。

Javaの多くのメソッドが標準的なエラー処理をサポートしています。また、自分でエラー処理を設計することも可能です。ただ、この授業の範囲では、自分でエラー処理を設計することはないと思います。標準的な機能の利用を練習しておきます。

次のプログラムを作って試してください。
引数が2個あることを前提としています。
なので、引数が少ないとエラーが出ます。確認してください。

 public class TestException {
 	public static void main(String argv[]){
 			System.out.println(argv[0]+" "+argv[1]);
 			System.out.println("Nice to meet you.");
 	}
 }

エラーが出る可能性のある場所をtryでくくっておき、
エラーが出たらそれを捕捉する処置をcatchで指定します。

 public class TestException {
 	public static void main(String argv[]){
 		try{	
 			System.out.println(argv[0]+" "+argv[1]);
 			System.out.println("Nice to meet you.");
 		}
 		catch (Exception e) {
 			System.out.println("please input 2 words.");
 		}
 	}
 }


**第10章 Stringクラスとコレクションフレームワーク [#w938c6ce]

以下のリンクからStringクラスを選択して、何ができるかざっと見ておきましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html


***Stringのメソッドをいくつか使ってみましょう [#v7994c3d]

 public class TestString {
     public static void main (String argue[]) {
 
     String str = "Hello Java World";
 
     //このstrを表示してください(System out.printlnを使う)
 
     //strの長さを表示してください(.lengthを使う))
 
     //strの3要素目の文字を表示してください
 
     //最初にaが現れる位置を表示してください
 
     //最後の文字aが現れる位置を表示してください
 
     //辞書式で比較してstrと次のstr2をcompareToを使って比較してください。順番を変えるとcompareToが返す値はどうなるでしょう?
     String str2="Have World";
 
     //strの6要素目から始まる部分文字列を作り表示して表示してください。
 
     //int型をString型に変換してください。
     int v2020=2020;
     String s2020 = String.valueOf(v2020);
 
     }
 }


解答例:

 public class TestString{
 	public static void main(String args[]){
 		String str = "Hello Java World";
 
 		System.out.println(str);
 		System.out.println(str.length());
 		System.out.println(str.charAt(3));
 		System.out.println(str.indexOf('a'));
 		
 		String str2 = "Hello World";
 
 		System.out.println(str.compareTo(str2));
 		System.out.println(str2.compareTo(str));
 
 		System.out.println(str.substring(6));
 
 		int v2020=2020;
 		String s2020 = String.valueOf(v2020);
 		System.out.println(s2020);
 	}
 }



***演習:引数の文字列を逆に表示するプログラムを作る [#nc1414b9]

最初の引数(文字列)を表示するプログラムは、以下です。クラス名はTestStringにしました。

 public class TestString {
	public static void main(String argv[]) {
		System.out.println(argv[0]);
	}
 }

これを元に、最初の引数(文字列)を逆に出力するプログラムを作ってください。例えば、ochanomizuと入力すると、以下のように表示されるプログラムを作ります。

 [e100:?/Documents/java] siio% java TestString ochanomizu
 ochanomizu
 uzimonahco
 [e100:?/Documents/java] siio% 
 
さらには、引数がない場合は引数入力を促すことを表示してみよう。
 
 [e100:?/Documents/java] siio% java TestString
 please input a word
 [e100:?/Documents/java] siio%

解答例:

 public class TestString {
 	public static void main (String argv[]) {
 		try{
 			System.out.println(argv[0]);
 			int len = argv[0].length();
 			for(int i = len - 1; i>=0; i--) {
 				System.out.print(argv[0].charAt(i));
 			}
 			System.out.println();
 		}
 		catch (Exception e) {
 			System.out.println("please input a word");
 		}
 	}
 }


***Linked List [#n28a2bc2]

https://docs.oracle.com/javase/jp/8/docs/api/index.html

要素があって、次の要素へのポインターを持っているような、リスト構造です。

 (element 1) ---> (element 2) ---> (element 3) ---> ...  ---> (element n)

次のプログラムを作ってLinked Listのメソッドを使ってみましょう。
定義とコンストラクタで<String>と書くのは、要素がStringのインスタンスだという宣言です。
昔のJavaでは不要だったのですが、今のバージョンではこのような形式で明示的に書かないといけないようです。

 import java.util.*;
 
 public class LinkedListTest{
         public static void main(String[] args) {
                 LinkedList<String> list = new LinkedList<String>();
                 String name1="ALICE";
                 String name2="BOB";
 
 //listにname1をaddしてください
 //listにname2をaddしてください
 //listの要素数を取得して表示してください
 //listから最初の要素をgetFirstで取り出して表示してください
 //listからget(1)してその結果を表示してください
 
                 String name3="CINDY";
                 String name4="DAVE";
  
 //listにname3をaddしてください。
 //listからname1を削除してください(remove)
 //listにname4をaddFirstしてください。
 //この結果、"DAVE" --> "BOB" --> "CINDY"となると思います。
 
 //listの全要素にアクセスするには、Iteratorインスタンスを作ると便利です。
 //以下のようにして全要素を表示してください。
 
         Iterator it = list.iterator();
     
         while(it.hasNext()) {
                 String st = (String)it.next();
                 System.out.println(st);
          }
 
 //toArrayメソッドで配列を作ることもできます
 //以下のようにして全要素を表示してください。
 
         Object[] names = list.toArray();
         for(Object s: names) System.out.println(s);
     }
 }


解答例:

 Import java.util.*;
 
 public class LinkedListTest{
 
 	public static void main(String args[]){
 
 	LinkedList<String> list = new LinkedList<String>();
 
 	String name1 = "ALICE";
 	String name2 = "BOB";
 
 	list.add(name1);
 	list.add(name2);
 	
 	System.out.println(list.size());
 	System.out.println(list.getFirst());
 	System.out.println(list.get(1));
 
 	String name3 = "CINDY";
 	String name4 = "DAVE";
 
 	list.add(name3);
 	list.remove(name1);
 	list.addFirst(name4);
 
 	Iterator it = list.iterator();
 	while(it.hasNext()) System.out.println(it.next());
 
 	Object[] names = list.toArray();
 	for(Object s: names) System.out.println(s);
 
 	}
 
 }

解答例(丁寧版):

 import java.util.*;
 
 public class LinkedListTest{
         public static void main(String[] args) {
                 LinkedList<String> list = new LinkedList<String>();
                 String name1="ALICE";
                 String name2="BOB";
                 list.add(name1);
                 list.add(name2);
                 String firstname=list.getFirst();
                 String secondname=list.get(1);
                 System.out.println("listの要素数は" + list.size());
                 System.out.println("listの最初の要素は" + firstname + "2番目の要素は" + secondname);    
                
                 String name3="CINDY";
                 String name4="DAVE";
                 list.add(name3); 
                 list.remove(name1);
                 list.addFirst(name4);
                
                 Iterator it = list.iterator();
                 System.out.println("要素の走査");
                 while(it.hasNext()){
                         String st = (String)it.next();
                         System.out.println(st);
                 }
                 
 
                 System.out.println("要素の走査 by toArray()");
                 Object[] names = list.toArray();
                 for(Object s: names) System.out.println(s);
 
         }
 }


***Hash Set [#h59a37b5]

https://docs.oracle.com/javase/jp/8/docs/api/index.html

Linked Listと同様にインスタンスの集まりを保持するデータ構造です。

 (element 1) ---> (element 2) ---> (element 3) ---> ... (element n)

だだし、同一要素を重複して保持しません。

 import java.util.*;
 
 public class HashSetTest{
     public static void main(String args[]){
         HashSet<String> set = new HashSet<String>();
         String name1="Alice";
         String name2="Bob";
         String name3="Cindy";
 
 //setにname1をaddしてください
 //setにname2をaddしてください
 //setにname3をaddしてください
 //setに再びname1をaddしてみてください。その時の戻り値 (booleanです)の状態を表示してください。
  
 //setの内容をIteratorを使って全部表示してください。
 
     }
 }

解答例:

 import java.util.*;
  
  public class HashSetTest{
      public static void main(String args[]){
          HashSet<String> set = new HashSet<String>();
          String name1="Alice";
          String name2="Bob";
          String name3="Cindy";
  
 //name1,2,3を追加
 	set.add(name1);
 	set.add(name2);
 	set.add(name3);
 //name1の再度追加を試みる。失敗
 	System.out.println(set.add(name1));
   
 	Iterator it = set.iterator();
 	while(it.hasNext())
 		System.out.println(it.next());
  
      }
  }



***Hash Map [#ac67b323]

https://docs.oracle.com/javase/jp/8/docs/api/index.html

2つのインスタンスのマッッピング(対応付け)の集まりを保持するクラスです。2つのインスタンスをキー(key)と値(value)と言います。例えば、keyもvalueもどちらもStringインスタンスの場合、以下のようにして要素を追加していきます。

 import java.util.*;
 
 public class EtoJ{
 
 public static void main(String args[]) {
 	HashMap<String,String> map = new HashMap<String,String>();
 	
 	map.put("apple","りんご");
 	map.put("banana","バナナ");
 ...
 
 }
 }

このプログラムで、mapインスタンスからkeyに対応するvalueを取り出すためには、

 map.get("apple");

などとします。


このプログラムを拡張して、以下のように動作する英語ー日本語単語変換プログラムを作ってください。

 [e100:?/Documents/java] siio% java EtoJ banana
 バナナ
 [e100:?/Documents/java] siio% java EtoJ apple
 りんご
 [e100:?/Documents/java] siio% java EtoJ 
 Please input an English word


解答例:

 import java.util.*;
 
 public class EtoJ{
 
 public static void main(String args[]) {
 	HashMap<String,String> map = new HashMap<String,String>();
 	
 	map.put("apple","りんご");
 	map.put("banana","バナナ");
 	map.put("orange","みかん");
 	map.put("pineapple","パイナップル");
 	map.put("grape","ぶどう");
 	map.put("peach","もも");
 	map.put("melon","メロン");
 	map.put("lemon","レモン");
 	
	try {
 	System.out.println(map.get(args[0]));
 	}
 	catch(Exception e) {
 	System.out.println("Please input an English word");
 	}
 
 	}
 }

**第11章 入出力 [#hb3a05b8]


Javaの入出力は、ファイル、ネットワーク、キーボード、ディスプレイを対象としています。C言語に比べて、高機能な上に、ネットワークへの入出力も標準装備されているところが便利です。

 (ファイル、ネットワーク、キーボード)
     |
     | 入力ストリーム
     |
     V
 (Javaプログラム)
     |
     | 出力ストリーム
     |
     V
 (ファイル、ネットワーク、ディスプレイ)

**バイトストリーム [#h69eaef6]

データを入出力するのがバイトストリームです。
ここでは、

- File Output Stream
- Data Output Stream
- File Input Stream
- Data Input Stream

を使ってみます。

*** File Output Streamを使ってバイト単位で書き出し [#e74b0e4e]

こちらで機能を確認しましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html

基本的なインスタンスメソッドは、writeとcloseです。writeには1バイトの書き込み、バイト配列の書き込みがあります。IOExceptionを投げるので、キャッチします。

 write(int b)

は、int型の引数の下位1バイトを書き出します。以下のプログラムでファイルに1バイト書き出すことができます。

 import java.io.*;
 
 public class FoutTest {
 	public static void main(String[] args) {
 		try {
 			FileOutputStream fout = new FileOutputStream("fout.dat");
 			fout.write(1234);
 			fout.close();
 		}
 		catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }

これでfout.datという名前のファイルができあがるはずです。 作ったファイルを

 hexdump fout.dat

してみてください

 $ hexdump fout.dat 
 0000000 d2                                             
 0000001

1234は0x4d2だったのでその下1バイトが書き込まれました。

***Data Output StreamでJava整数型データを出力する [#l6a1be55]

こちらで機能を確認しましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html

Javaのいろいろなデータ型を書き出すことができます。
int, long, short, float, double, booleanなどのデータを書き出します。
以下では、int型データを書き出しています。
なお、Data Output StreamはFile Output Streamの機能を利用しています。
Data Output Streamのコンストラクトには、File Output Streamのインスタンスが必要です。
なので2段階のコンストラクト作業になります。



 import java.io.*;
 
 public class DoutTest {
 	public static void main (String[] args) {
 		try {
 			FileOutputStream fout = new FileOutputStream("dout.dat");
 			DataOutputStream dout = new DataOutputStream(fout);
 			dout.writeInt(100);
 			dout.close();
 			
 		}catch (Exception e) {
 			System.out.println(e);
 		}
	}
 }

これでdout.datという名前のファイルができあがるはずです。 作ったファイルを

 hexdump dout.dat

してみてください

 e100:java siio$ hexdump dout.dat 
 0000000 00 00 00 64                                    
 0000004

int型は4バイトなので4バイトのファイルが出来上がっています。100は0x000064なので、その内容のファイルです。


***整数を入出力する例 [#j899e2e7]

File/Data Output Streamにはそれぞれ対応したFile/Data Input Streamがあります。
こちらで機能を確認しましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html

Javaのint型のデータで100をファイルに書いて、これを読み込む例です。

 import java.io.*;
 
 public class DoutTest {
 	public static void main (String[] args) {
 		try {
 			FileOutputStream fout = new FileOutputStream("dout.dat");
 			DataOutputStream dout = new DataOutputStream(fout);
 			dout.writeInt(100);
 			dout.close();
 			
 			FileInputStream finput = new FileInputStream("dout.dat");
 			DataInputStream dinput = new DataInputStream(finput);
 			System.out.println(dinput.readInt());
 			dinput.close();
 			
 		}catch (Exception e) {
 			System.out.println(e);
 		}
 	}
 }


***演習 [#iffeaa5d]

1から100までのint型の数値をwirteIntメソッドでファイルに書き出すプログラムを書いてください。また、そのファイルをreadIntメソッドで読み込み、表示してください。

作ったファイルを
 hexdump dout.dat
してみてください

解答例


 import java.io.*;
 
 public class DoutTest {
 	public static void main (String[] args) {
 		int i;
 		try {
 			FileOutputStream fout = new FileOutputStream ("dout.dat");
 			DataOutputStream dout = new DataOutputStream(fout);
 			for(i=1;i<101;i++) dout.writeInt(i);
 			dout.close();
 			
 			FileInputStream fin = new FileInputStream ("dout.dat");
 			DataInputStream din = new DataInputStream(fin);
 			
 			for(i=1;i<101;i++) System.out.println(din.readInt());
 			din.close();
 			
 		} catch (FileNotFoundException e) {
 			System.out.println(e);
 		} catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }


**文字ストリーム [#x25291f2]

文字を読み書きするのが文字ストリームです。文字に適した処理が用意されています。
ReaderとWriterというクラスのグループがあります。

***文字列の書き出し [#a85525d6]

File Writerを使うと文字列を書き出すことができます。
close, flush, writeなどのメソッドがあります。
こちらで機能を確認しましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html

File Writerにはwrite()メソッドで、文字や、文字配列や、Stringを書き出すことができます。
以下ではStringを書き出しています。

 import java.io.*;
 
 public class PrintWriterTest{
 	public static void main(String[] args) {
 		try {
 		//writer.txtというファイルを作って文字を書き込む
 			FileWriter fwriter = new FileWriter("writer.txt");
 			fwriter.write("Multimedia Programming 実習");
 			fwriter.close();	
 		}
 		catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }


また、Print Writerというクラスでは、System Out Printlnのようにprintlnに相当する機能が使えます。
Javaのいろいろなデータを書き出すのに便利です。


***printlnで書き出すプログラム [#efb2dbc9]

writer.txtというファイルに、

 int x = 2020;
 String s = "Multimedia Programming 実習";

というJavaの変数を、printlnで書き出すプログラムを作ってください。

//Print Writerをコンストラクトするためには、File Writerのインスタンスが必要です。なので、これも2段階のコンストラクションを行います。

 import java.io.*;
 
 public class PrintWriterTest{
 	public static void main(String[] args) {
 		try {
 		//writer.txtというファイルを作って文字を書き込む
 			PrintWriter pwriter = new PrintWriter("writer.txt");
 			pwriter.println(2020);
 			pwriter.println("Multimedia Programming 実習");
 			pwriter.close();	
 		}
 		catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }


作ったファイルを hexdump してみてください

 $ hexdump writer.txt 
 0000000 32 30 32 30 0a 4d 75 6c 74 69 6d 65 64 69 61 20
 0000010 50 72 6f 67 72 61 6d 6d 69 6e 67 20 e5 ae 9f e7
 0000020 bf 92 0a                                       
 0000023

hexdump -cでキャラクタ表示にもなります。

 $ hexdump -c writer.txt 
 0000000   2   0   2   0  \n   M   u   l   t   i   m   e   d   i   a    
 0000010   P   r   o   g   r   a   m   m   i   n   g       ?   ? 237   ?
 0000020   ? 222  \n                                                    
 0000023

2020という数値は、int型なのですが、ASCII文字列に変換されて文字として書き出されていることがわかります。
「Multimedia Programming 実習」は、もともとが文字列なので、そのまま文字列として書き出されています。0x0Aは改行コードです。
int型などのデータを文字に自動変換してくれるところが、Print Writerの特徴です。
Stringだけでしたら、File Writerの機能を使っても同様に書き出すことが可能です。



***read Lineで改行コードまでを読み込む [#y3262833]

File ReaderはFile Writerと同様に文字列を読み込みます。
読み込む文字数を指定して読み込むことも可能です。
さらに便利なクラスがBuffered Readerで、こちらは改行文字までを読み込んでくれます。
こちらで機能を確認しましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html

Buffered ReaderもFile Readerのインスタンスから作りますので、2段階のコンストラクションになります。

writer.txtというテキストファイルがあるとして、これから1行ずつ読み込んで画面表示するプログラムは以下のようになります。

 public class BufferedReaderTest{
 	public static void main(String[] args) {
 		try {
 			FileReader freader = new FileReader("writer.txt");
 			BufferedReader breader = new BufferedReader(freader);
 			String tmp;
 			while( (tmp=breader.readLine() ) != null) {
 				System.out.println(tmp);
 			}
 			breader.close();
 		}
 		catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }

このプログラムを参考にして、
先のPrint Writer Testに書き足して、
書き込んだデータを読み出して画面に表示するプログラムを作ってください。

ヒント:

 import java.io.*;
 
 public class PrintWriterTest{
 	public static void main(String[] args) {
 		try {
 		//writer.txtというファイルを作って文字を書き込む
 			PrintWriter pwriter = new PrintWriter("writer.txt");
 			pwriter.println(2020);
 			pwriter.println("Multimedia Programming 実習");
 			pwriter.close();	
			 
			 
			 ここに書き足す
			 
			 
 		}
 		catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }



解答例:


 import java.io.*;
 
 public class PrintWriterTest{
 	public static void main(String[] args) {
 		try {
 		//writer.txtというファイルを作って文字を書き込む
 			PrintWriter pwriter = new PrintWriter("writer.txt");
 			pwriter.println(2020);
 			pwriter.println("Multimedia Programming 実習");
 			pwriter.close();			
 		//writer.txtのファイルの中身をSystem.out.printlnで表示する
 			FileReader freader = new FileReader("writer.txt");
 			BufferedReader breader = new BufferedReader(freader);
 			String tmp;
 			while( (tmp=breader.readLine() ) != null) {
 				System.out.println(tmp);
 			}
 			breader.close();
 		}
 		catch (IOException e) {
 			System.out.println(e);
 		}
 	}
 }


**標準入出力 [#u09d26a5]

標準入出力には、

- キーボードからプログラムへの標準入力
- プログラムからディスプレイへの標準出力
- エラー出力

の3種類があります。これらはJavaのクラス変数として定義されています。

- System.in キーボードからプログラムへの標準入力
- System.out プログラムからディスプレイへの標準出力
- System.err エラー出力

それぞれの型は、

- System.in は Input Stream型
- System.out は Print Stream型
- System.err は Print Stream型

です。使えるメソッドはこちらで確認できます。

https://docs.oracle.com/javase/jp/8/docs/api/index.html

***標準入力から読み込んだ文字列をそのままディスプレイに表示するプログラム [#mcb98bfc]

 import java.io.*;
 
 public class StandardIOTest {
 	public static void main(String[] args) {
 	
 		try {
 			//System.inからInputStreamReaderを作り、それからBufferedReaderを作る
 			InputStreamReader ireader = new InputStreamReader (System.in);
 			BufferedReader breaderK = new BufferedReader(ireader);
 			
 			System.out.println("文字列を入力してリターンを押してください");
 			String line = breaderK.readLine();
 			System.out.println("あなたが入力した文字列" + line);

 			}
		catch(IOException e) {
 				System.out.println(e);
 			}
 	}
 }

***演習 [#m02d0351]

キーボードから1行入力された文字列から writer.txtという名前のテキストファイルを作るプログラムを作ってください。

//http://gyazo.com/f9aee7f492d574f870e85e2022df374c.png

 e100:java siio$ java KeyToFile 
 Hello, これはテストです。
 Hello, これはテストです。
 e100:java siio$ cat writer.txt 
 Hello, これはテストです。

ヒント

  import java.io.*;
  
  public class KeyToFile {
  	public static void main(String[] args) {
  	
  		try {
 
 
 ここにプログラムを書く
  		
  			}
 		catch(IOException e) {
  				System.out.println(e);
   			}
     }
  }



解答例

 import java.io.*;
 
 public class KeyToFile {
 	public static void main(String[] args) {
 	
 		try {
 			InputStreamReader ireader = new InputStreamReader (System.in);
 			BufferedReader breaderK = new BufferedReader(ireader);
 			String line = breaderK.readLine();
 			
 			PrintWriter pwriter = new PrintWriter("writer.txt");
 			pwriter.println(line);
 			pwriter.close();
 			
 			FileReader freader = new FileReader("writer.txt");
 			BufferedReader breaderF = new BufferedReader(freader);
 			
 			String tmp=null;		
 			while(  (tmp=breaderF.readLine())  != null)
 				System.out.println(tmp);
 			
 			breaderF.close();
 		
 			}
			catch(IOException e) {
 				System.out.println(e);
 			}
 	}
 }


***http://www.ocha.ac.jp/の内容を表示するプログラムを書いてみよう [#kf0c5bf6]

http://gyazo.com/13044fdd9d372118a1f6fe93896eadb3.png

ヒント1

以下のリンクからURLクラスを選択して、調べましょう。

https://docs.oracle.com/javase/jp/8/docs/api/index.html


ヒント2

 import java.net.*;

が必要です。

 URL targetURL = new URL("http://www.ocha.ac.jp/");

でURLクラスのインスタンスが得られる。

 InputStream istream = targetURL.openStream();

でこれからInputStreamのインスタンスが得られる。

 InputStreamReader isreader = new InputStreamReader(istream);

でこれからInputStreamReaderのインスタンスが得られる。

 BufferedReader breader = new BufferedReader(  isreader );

でこれからBufferedReader のインスタンスが得られる。

ヒント3


 import java.io.*;
 import java.net.*;
 
 public class URLTest {
 	public static void main (String argv[]) {
 		try {
 			
			 
			 ここにプログラムを書く
			 
			 
 		} catch (IOException e) {
 			System.out.println("error...");
 		}
 	}
 }


ヒント4:

 import java.io.*;
 import java.net.*;
 
 public class URLTest {
 	public static void main (String argv[]) {
 		try {
 			URL targetURL = new URL("http://www.ocha.ac.jp/");
 			InputStream istream = targetURL.openStream();
 			InputStreamReader isreader = new InputStreamReader(istream);
 			BufferedReader breader = new BufferedReader(  isreader );
 		
 ここで一行ずつ読み込む
 
 		} catch (IOException e) {
 			System.out.println("error...");
 		}
 	}
 }



解答例:

 import java.io.*;
 import java.net.*;
 
 public class URLTest {
 	public static void main (String argv[]) {
 		try {
 			URL targetURL = new URL("http://www.ocha.ac.jp/");
 			InputStream istream = targetURL.openStream();
 			InputStreamReader isreader = new InputStreamReader(istream);
 			BufferedReader breader = new BufferedReader(  isreader );
 		
 			String line;
 			while((line=breader.readLine()) != null) System.out.println(line);
 		
 		} catch (IOException e) {
 			System.out.println("error...");
 		}
 	}
 }


***写真ファイルのダウンロード [#edb3e256]

 http://siio.jp/cat.jpg 

をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。
データはテキストじゃなくて、バイナリーです。

ヒント1:

InputStreamのインスタンスに対してread()メソッドを使うと1バイトのデータが得られます。読み終わると-1になります。
1バイトのデータを書き出すなら、FileOutputStreamだけで可能です。

ヒント2:

 import java.io.*;
 import java.net.*;
 
 public class URLJpeg {
 	public static void main (String argv[]) {
 		try {
 			URL targetURL = new URL("http://siio.jp/cat.jpg");
 			InputStream istream = targetURL.openStream();
 			
 			FileOutputStream fout = new FileOutputStream("cat.jpg");


というインスタンスを作って、

 istream.read()

で読んで、

 fout.write(1バイト)

で書き出します。

解答例

 import java.io.*;
 import java.net.*;
 
 //http://siio.jp/cat.jpg
 //をダウンロードして、cat.jpgというファイルを作るプログラム
 
 public class URLJpeg {
 	public static void main (String argv[]) {
 		try {
 			URL targetURL = new URL("http://siio.jp/cat.jpg");
 			InputStream istream = targetURL.openStream();
 			
 			FileOutputStream fout = new FileOutputStream("cat.jpg");
 			
 			int aData;
 			while((aData  = istream.read()) != -1) fout.write(aData);
 			
 			istream.close();
 			fout.close();
 			
 			
 		} catch (IOException e) {
 			System.out.println("error...");
 		}
 	}
 }



***本日のレポート [#o4524903]

上記のプログラム(URLJpeg.java, URLJpeg.class) を、出席番号+名前のフォルダにいれて、ZIP圧縮して提出してください。`


***写真読み込みの高速化 [#ia7ce1f8]

上記の例では写真データを1バイトずつ読み書きしていました。
InputStreamのメソッドを調べると、複数バイト単位で読み込むメソッドがあります。
たとえば、1024バイトずつ読み書きすることで、処理速度が向上すると期待できます。
そこで、複数バイト読み書きするよう、上記のプログラムを変更して、
実際にどの程度(実行速度にして何倍くらい)性能向上するか確認してみましょう。


 read
 
 public int read(byte[] b)
          throws IOException
 入力ストリームから配列長さだけのバイト数を読み込もうとし、それをバッファ配列 b に格納します。
 実際に読み込まれたバイト数は整数として返されます。
 戻り値は、バッファに読み込まれたバイトの合計数。ストリームの終わりに達してデータがない場合は -1

を使って読みこみ、

 write
 
 public void write(byte[] b,
                   int off,
                   int len)
            throws IOException
 指定された byte 配列の、オフセット位置 off から始まる len バイトを出力ストリームに書き込みます。

を使ってください。

-ヒント


 byte[] data = new byte[1024];

という配列を用意して、

 	int datalength;
 	while(( datalength=istream.read(data)) != -1) fout.write(data, 0, datalength);

とします。

-解答例

 import java.io.*;
 import java.net.*;
 
 //http://siio.jp/cat.jpg
 //をダウンロードして、cat.jpgというファイルを作るプログラムを作ってください。
 //データはテキストじゃなくて、バイナリーです。
 
 public class URLJpeg2 {
 	public static void main (String argv[]) {
 		byte[] data = new byte[1024];
 		try {
 			URL targetURL = new URL("http://siio.jp/cat.jpg");
 			InputStream istream = targetURL.openStream();
 			
 			FileOutputStream fout = new FileOutputStream("cat.jpg");
 			
 			int datalength;
 			while(( datalength=istream.read(data)) != -1) fout.write(data, 0, datalength);
 			
 			istream.close();
 			fout.close();
 			
 			
 		} catch (IOException e) {
 			System.out.println("error...");
 		}
 	}
 }


ここでは1024バイトを読み込むことにしました。でも、InputStreamのメソッドを見ると、available()というのがあります。

 available()
 この入力ストリームのメソッドの次の呼出しによって、ブロックせずにこの入力ストリームから読み込むことができる(またはスキップできる)推定バイト数を返します。

これを使えば、適切な長さを見積もれるかもしれません。

***引数のURLをファイルにするプログラムを考えてみましょう [#mc747214]

curlというコマンドがあります。

 curl http://ocha.ac.jp/

などとすると、htmlが見られますし、

 curl http://siio.jp/cat.jpg > cat.jpg

などとすると、ファイルとして保存できます。これに近いプログラムを作ってみましょう。



***宿題 [#wb66142e]

上記の引数のURLをファイルにするプログラムを作ってください。
また、cat.jpgのファイル取得でまとめて読むことでどれくらい速度が改善したかを、
レポートにしてください。レポートの書式は任意です。(テキストファイルでかまいません)

これらのjava, class, レポートのファイルをまとめて、出席番号+名前のフォルダに入れて、圧縮して、12月10日の授業の開始時間に提出してください。


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS