このページは、学部2年生向け授業である、「マルチメディアプログラミング実習」 のために用意しました。
(Wikiの仕様で大文字小文字が混在した英単語に疑問符?が追加されるところがありますが、無視してください。)
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."); } } }
以下のリンクからStringクラスを選択して、何ができるかざっと見ておきましょう。
https://docs.oracle.com/javase/jp/8/docs/api/index.html
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); } }
最初の引数(文字列)を表示するプログラムは、以下です。クラス名は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"); } } }
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); 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); } }
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 set = new HashSet(); String name1="Alice"; String name2="Bob"; //setにname1をaddしてください //setにname2をaddしてください //setに再びname1をaddしてみてください。その時の戻り値 (booleanです)の状態を表示してください。 } }
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("りんご");
などとします。
このプログラムを拡張して、以下のように動作する英語ー日本語単語変換プログラムを作ってください。
[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"); } } }
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という名前のファイルができあがるはずです。 作ったファイルを
od -h fout.dat
または
hexdump fout.dat
してみてください
$ hexdump fout.dat 0000000 d2 0000001
1234は0x4d2だったのでその下1バイトが書き込まれました。
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という名前のファイルができあがるはずです。 作ったファイルを
od -h dout.dat
または
hexdump dout.dat
してみてください
e100:java siio$ hexdump dout.dat 0000000 00 00 00 64 0000004
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); } } }
作ったファイルを
od -h dout.dat
または
hexdump dout.dat
してみてください
解答例
import java.io.*; public class En111 { 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); } } }
作ったファイルを
od -h
または
hexdump
してみてください
import java.io.*; public class PrintWriterTest{ public static void main(String[] args) { try { //writer.txtというファイルを作って文字を書き込む FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println(2006); pwriter.println("Java教科書"); //fwriter.write("Java教科書"); pwriter.close(); } catch (IOException e) { System.out.println(e); } } }
つぎに、プログラム11.4を参考にして、 このPrint Writer Testに書き足して、 書き込んだデータを読み出して画面に表示するプログラムを作ってください。
ヒント:
import java.io.*; public class PrintWriterTest{ public static void main(String[] args) { try { //writer.txtというファイルを作って文字を書き込む FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println(2006); pwriter.println("Java教科書"); //fwriter.write("Java教科書"); pwriter.close(); ここに書き足す } catch (IOException e) { System.out.println(e); } } }
import java.io.*; public class PrintWriterTest{ public static void main(String[] args) { try { //writer.txtというファイルを作って文字を書き込む FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); pwriter.println("java 教科書" + 2001 ); 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); } } }
キーボードから1行入力された文字列によるテキストファイルを作る
ヒント
import java.io.*; public class En112 { public static void main(String[] args) { try { ここにプログラムを書く } catch(IOException e) { System.out.println(e); } } }
解答例
import java.io.*; public class En112 { public static void main(String[] args) { try { InputStreamReader ireader = new InputStreamReader (System.in); BufferedReader breaderK = new BufferedReader(ireader); String line = breaderK.readLine(); FileWriter fwriter = new FileWriter("writer.txt"); PrintWriter pwriter = new PrintWriter(fwriter); 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); } } }
ヒント1
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 のインスタンスが得られる。
ヒント2
import java.io.*; import java.net.*; public class URLTest { public static void main (String argv[]) { try { ここにプログラムを書く } catch (IOException e) { System.out.println("error..."); } } }
ヒント3:
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..."); } } }
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..."); } } }
上記のプログラム(URLJpeg.java, URLJpeg.class) を、出席番号+名前のフォルダにいれて、ZIP圧縮して提出してください。`
上記の例では写真データを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() この入力ストリームのメソッドの次の呼出しによって、ブロックせずにこの入力ストリームから読み込むことができる(またはスキップできる)推定バイト数を返します。
これを使えば、適切な長さを見積もれるかもしれません。
curlというコマンドがあります。
curl http://ocha.ac.jp/
などとすると、htmlが見られますし、
curl http://siio.jp/cat.jpg > cat.jpg
などとすると、ファイルとして保存できます。これに近いプログラムを作ってみましょう。
上記の引数のURLをファイルにするプログラムを作ってください。 また、cat.jpgのファイル取得でまとめて読むことでどれくらい速度が改善したかを、 レポートにしてください。レポートの書式は任意です。(テキストファイルでかまいません)
これらのjava, class, レポートのファイルをまとめて、出席番号+名前のフォルダに入れて、圧縮して、12月10日の授業の開始時間に提出してください。