Javaの入出力:java.ioパッケージ

プログラミング第三
第1部 オブジェクト指向・Java復習

Java API
 入出力 : java.io パッケージ
 GUI : java.awt, javax.swing パッケージ
Javaの入出力:java.ioパッケージ

ファイル、通信接続先、メモリ領域などへの
入出力を汎用的に行なうクラス集合


ポイント:連続するデータ(Stream) として抽象化
重要なクラス

InputStream, OutputStream
Byte Streamを表現する抽象クラス
 Byte単位での読み書きを行う


Reader, Writer
Character Streamとして入出力を扱う
 文字単位での入出力処理を表現する抽象クラス

3
1
Byte Streamを表現するクラス
例: InputStreamの子クラス:Byte単位入力

(
InputStream
)
ファイルシステムから
rawデータを読み込み
FileInputStream
メモリ上のデータ列用
ByteArrayInputStream
スレッド間通信用
PipedInputStream
直列化されたオブジェクト
を読み込む
ObjectInputStream
(
FilterInputStream
)
DataInputStream
InputStreamに
拡張機能を提供
する
BufferedInputStream
PushbackInputStream
OS非依存で
プリミティブ型
を読込む拡張
バッファ機能拡張
読み戻し機能拡張
4
InputStream/OutputStreamの主なメソッド
InputStreamの主なメソッド

int read ();



入力ストリームから
b.lengthバイト読み,
bに格納
入力ストリームから次
のnバイトを読み飛ばす
void close ();

入力ストリームを閉じ
て,後始末
void write (int b);



出力ストリームにバイ
ト列bを書く
void flush ();


出力ストリームにバイ
ト値bを書く
void write (byte[] b);

long skip (long n);



入力ストリームから次
のバイトを読む
int read (byte[] b);

OutputStreamの主なメソッド
出力ストリームをフラ
ッシュ
void close ();

出力ストリームを閉じ
て,後始末
5
2
文字単位での入出力処理を表現するクラス

例: Readerの子クラス:文字単位入力
(
Reader
)
ファイルシステム
FileReader
文字列用
StringReader
PipedReader
スレッド間通信用
InputStreamReader
InputStreamからの変換を行う.
バイトを読み込み、指定された
charset を使用して文字に変換する
( FilterReader )
バッファ機能拡張
BufferedReader
読み戻し機能拡張
PushbackReader
6
Reader/Writerの主なメソッド
Readerの主なメソッド

int read ();




入力ストリームから
c.length個文字読み,
cに格納
long skip (long n);

入力ストリームから次のn
文字を読み飛ばす
void close ();


入力ストリームから次の
文字を読む
int read (char[] c);

Writerの主なメソッド
入力ストリームを閉じて
,後始末
void write (int c);


void write (char[] c);


出力ストリームに文字列s
を書く
void flush ();


出力ストリームに文字の
配列cを書く
void write (String s);


出力ストリームにcで指定
された文字 を書く
出力ストリームをフラッ
シュ
void close ();

出力ストリームを閉じて
,後始末
7
3
コード例:ファイルの読み書き
import java.io.*;
簡略化のため
例外処理はしていない
class TestIO{
public static void main(String[] args) throws IOException{
InputStream is;
OutputStream os;
ファイル名を引数にすると
___________
is = new FileInputStream(args[0]);
os = new FileOutputStream(args[1]);
______
Pass.pass(is, os);
の派生クラス
byte[] b= {72,101,108,108,111,33,33,10};
% java TestIO ./TestIO.java ./text.txt
is = new ByteArrayInputStream(b);
Hello!!
os = System.out;
%cat ./text.txt
Pass.pass(is, os);
SystemクラスのStatic変数out Import java.io.*;
}
}
その実体は_____________を ….
継承した______________
(以下省略)
class Pass{
public static void pass(InputStream is, OutputStream os) throws IOException{
int c;
while((c=is.read())!= -1){
os.write(c);
___判定
基底クラスを引数にする
}
}
ことで____がある!
_byteずつ読む
8 }
機能拡張:バッファリング

BufferedInputStream, BufferedOutputStream


バッファリングで入出力の効率を向上.
例:8MBのファイルの読み込み.


FileInputStream=21秒.BufferedInputStream=1.6秒.
利用方法

他のストリームを引数で渡し内部に保持
InputStream is = new FileInputStream(“foo.txt”);

InputStream is =
new BufferedInputStream(new FileInputStream("foo.txt"));
10
4
機能拡張:StreamReader/Writer
Javaプログラム
中文字
PrintWriter
OutputStreamWriter
OutputStream
ファイル中
のデータ
char c = 'a';
Unicode
(2バイト)
'a'
InputStream
InputStreamReader
BufferedReader
ASCII, JIS,
EUC-JP, SJIS,
ISO-8299-1,...
(1バイト以上)
11
機能拡張:StreamReader/Writer
class Pass2{
public static void pass(InputStream is,
OutputStream os) throws IOException{
int counter=0;
int c;
while((c=is.read())!= -1){
if(counter==5){
break;
}
os.write(c);
counter++;
5_____ 読み書き
}
os.flush();
}
}
class Pass3{
public static void pass(InputStream is,
OutputStream os) throws IOException{
int counter=0;
int c;
Reader r = new InputStreamReader(is);
Writer w = new OutputStreamWriter(os);
while((c=r.read())!= -1){
if(counter==5){
break;
}
w.write(c);
5_____読み書き
counter++;
}
w.flush();
}
}
TestIOの中のPassをPass2やPass3に置き換えて実行すると….
%cat a.txt
こんにちは、世界
%java TestIO a.txt b.txt
%cat a.txt
こんにちは、世界
%java TestIO a.txt b.txt
%cat b.txt
%cat b.txt
13
5
機能追加:書式機能 (PrintWriter)

Writerに print, printlnを追加.


System.outとSystem.errはPrintStream


print(10); は文字列"10"を出力.C言語のprintfに相当
参考: System.inはInputStream
※ 歴史的経緯によりPrintStreamが残っている
がPrintWriterを使うことを推奨
new PrintWriter(outputstream, true);
new PrintWriter(
new OutputStreamWriter(outputstream,”EUC-JP”),
true);
出力したい
文字コードを
指定
15
printlnなどで、
Bufferをflushする
ことを指定
参考:Unicode

日本語など,世界の主要な文字を含む


広く利用されるUTF-8では1文字を可変長
(1~4バイト)で表現


大抵は2バイトで収まる
0∼127の文字コードはASCIIと同じ.



UTF-8, UTF-16などの複数の符号化方式が存在
ただし表現するバイト数は違う点に注意
unicode では __バイト,ASCIIでは __バイト
Javaのchar型はUnicode.

つまり,Javaの文字列はバイトストリームで単
純に扱えない
16
6
参考:データ・オブジェクトの直列化

直列化(serialize)

オブジェクトをバイトストリームに変換する
 簡略化した捉え方:
int型のフィールドを2つ持つ Object Aは,int型
を表現するデータを2つ並べれば表現できる.
つまり,(クラス定義と)このbyte streamを転送
すれば復元可能
DataInputStream, DataOutputStream




intやdoubleなどの入出力に使う
環境の差異(バイトオーダー)を無視できる
ObjectInputStream, ObjectOutputStream

オブジェクトの入出力(serialize)に使う
17
プログラミング第三
第1部 オブジェクト指向・Java復習

Java API
 GUI (java.awt, javax.swing)
7
GUI プログラムの特徴

Event Driven(イベント駆動型)
mainから順番に処理がされるのではない
 「あるイベントが起こったらこの処理」


ウィンドウ設計 (部品の配置)

出力に文字列以外も使える
 画像

入力にキーボード以外も使える
 ポインティングデバイス
19
イベント駆動型のプログラミング

イベントハンドラが実行される仕組み

イベントが発生
 ボタンが押された、マウスでクリックされた
イベントを待ち行列に格納
 登録したイベントリスナが対応処理

D-2) 待ち行列に
格納
L-1) 監視したいイベントを指定して
登録する
D-1) イベント
の発生
D-3) 登録されている
各リスナーに順番に通知
L-2) 通知が来たら,イベント用の
処理(イベントハンドラ)を実行
する (それまではなにも
実行していない)
20
8
GUI: ウィンドウ設計

共通化された部品(コンポーネント)を
配置することで複雑なUIを構築する
部品
21
Swing
Java2 SDKに含まれるGUIライブラリ
 パッケージ名は,javax.swing

通常,次をimportしてSwingを使う.
 javax.swing.*, java.awt.*, java.awt.event.*


実装手順
部品のオブジェクトを生成
 部品の配置
 イベント処理の設定

22
9
Swing GUIの構成要素

トップレベルコンテナ(ウィンドウなど)

JFrame, JDialog, Japplet
JFrameはメニューバー付きのウィンドウも作れる高
機能版
 JDialogはloginウィンドウや、警告ウィンドウ用の単
純版


中間コンテナ



JPanel, JScrollPane, JTabbedPane, JLayeredPane, …
コンポーネントを乗せるお盆。中間コンテナを
使わずにトップレベルコンテナにコンポーネン
トを直接乗せることもできる。
コンポーネント

JButton, JLabel, JTextField, JTextArea, …

様々な機能を持ったGUIの部品
23
Swing GUIによる構成例

JFrameを使用した例:
タイトル
JFrame
Menu
Bar
JButton
Content
Pane
JFrame
Content
Pane
Menu
Bar
その他
JButtonなど
左図のコンテナ階層構造
※コンテナ階層のトップは
必ずトップレベルコンテナにする.
24
10
部品の配置

JFrameのコンテナを得る.



例:Container container = frame.getContentPane();
部品のレイアウト(並べ方)を指定.

例:container.setLayout (new BorderLayout());

BorderLayout は東西南北と中央に配置するレイアウ
トマネージャ.他にも BoxLayout, CardLayout,
GridBagLayout, GroupLayout, SpringLayoutなどがある
部品を配置


例:container.add (textarea, BorderLayout.CENTER);
例:container.add (button, BorderLayout.NORTH);
25
Jframeを利用した例
import javax.swing.*;
class Test1 {
public static void main (String[] args) {
final JFrame frame = new JFrame ("Window1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize (300, 200);
frame.add(new JButton(“push”));
SwingUtilities.invokeLater(new Runnable(){
public void run(){
frame.setVisible (true);
}});
}
}
26
11
イベント処理の詳細



「イベント」を受け取って処理する
ActionListener(インターフェース)を定義する
GUIコンポーネントにActionListenerを登録する
( addListener() を使ってlistenersに追加する)
キー入力やマウス操作の内容は「イベント」として,
GUIコンポーネントに渡され, 各
ActionListener#actionPerformed()を呼び出すことで
処理が起動される
JButtonの
実体
ボタン押下
のイベント
登録
ActionListenerの
実体
メソッド呼び出し
actionPerformed()
27
例:JButtonにイベントハンドラを追加
import java.awt.event.*;
import javax.swing.*;
public class Notifier implements ActionListener{
public Notifier(){
}
public void actionPerformed(ActionEvent e){
System.out.println("pushed!");
}
public static void main(String[] args){
final JFrame jframe = new JFrame("EventTest");
JButton jbutton = new JButton("push me");
jbutton.addActionListener(new Notifier());
jframe.add(jbutton);
jframe.pack();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
jframe.setVisible (true);
}});
}
}
%javac Notifier.java
%java Notifier
pushed!
pushed!
部品の大きさで
ウィンドウの大きさを決定
ウィンドウ表示
28
12
マウスを使ったサンプル
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Drawing2 extends JPanel implements
MouseMotionListener, ActionListener {
volatile Point pnt = new Point(0,0);
volatile private Boolean clear=true;
public Drawing2(){
addMouseMotionListener(this);
}
public void paintComponent(Graphics g){
if(clear){
g.clearRect(0,0,600,400);
clear=false;
}else{
g.fillRect(pnt.x,pnt.y,2,2);
}
}
public void mouseDragged(MouseEvent e){
pnt = e.getPoint();
repaint();
}
public void mouseMoved(MouseEvent e){
}
public void actionPerformed(ActionEvent e){
clear = true;
repaint();
}
public static void main(String[] args){
final JFrame jframe = new JFrame("mouseEventTest");
Drawing2 drawing = new Drawing2();
drawing.setPreferredSize(new Dimension(600,400));
JButton jbutton = new JButton("clear");
jbutton.addActionListener(drawing);
Container container = jframe.getContentPane();
container.setLayout(new BorderLayout());
jframe.add(drawing,BorderLayout.NORTH);
jframe.add(jbutton,BorderLayout.SOUTH);
jframe.pack();
jframe.setResizable(false);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable(){
public void run(){
jframe.setVisible (true);
}});
}
}
29
マウスを使ったサンプル
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Drawing2 extends JPanel implements
MouseMotionListener, ActionListener {

JPanelのSubclassとして作成


MouseMotionListener

追加属性

volatile Point pnt = new Point(0,0);
volatile private Boolean clear=true;


public Drawing2(){
addMouseMotionListener(this);
}
public void paintComponent(Graphics g){
if(clear){
g.clearRect(0,0,600,400);
clear=false;
}else{
g.fillRect(pnt.x,pnt.y,2,2);
}
}
public void mouseDragged(MouseEvent e){
pnt = e.getPoint();
repaint();
}
JPanel の実装を継承して利用

マウスの移動イベントをListen
pnt という座標(Point)
clear というフラグ
描画処理:clearが真なら領域を
クリアそうでないならば 点を
描画
fillRect(int x, int y, int width, int height)
(x,y)を左端上端として,width*heightの
矩形を塗りつぶす.

マウスがドラッグされた時の
イベントハンドラ

イベントに含まれている座標を pnt
属性として,再描画する
30
13
マウスを使ったサンプル

public void mouseMoved(MouseEvent e){
}
public void actionPerformed(ActionEvent e){
clear = true;
repaint();
}

マウスカーソルが移動したときのハン
ドラ:何もしない
ActionEventが来た場合のハンドラ

public static void main(String[] args){
final JFrame jframe = new JFrame("mouseEventTest");
Drawing2 drawing = new Drawing2();
drawing.setPreferredSize(new Dimension(600,400));
JButton jbutton = new JButton("clear");
jbutton.addActionListener(drawing);
Container container = jframe.getContentPane();
container.setLayout(new BorderLayout());
jframe.add(drawing,BorderLayout.NORTH);
jframe.add(jbutton,BorderLayout.SOUTH);
jframe.pack();
jframe.setResizable(false);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable(){
public void run(){
jframe.setVisible (true);
}});
}




clearフラグをセットしてrepaint
Panel(Drawing2)のサイズを指定
作成したボタンのリス何登録
フレームサイズの変更不可
Closeボタンを押された時の振る舞い
規定されている EXIT_ON_CLOSEを設定
}
31
イベント処理の流れ
MouseMotionListener
MouseDragged()
MouseMoved()
MouseMotionListener
インタフェース
の実装として呼出
ActionListener
MouseEvent
actionPerformed()
MouseEvent
ActionListener
インタフェース
の実装として呼出
ActionEvent
Drawing2
Point pnt
boolean clear
paintComponent(g){
pnt clearを使っての
実際の描画実装
}
mouseDragged(){
pntに値をセット
repaint();
}
mouseMoved(){
}
actionPerformed(){
clearに値をセット
repaint();
}
JPanel
repaint()
paintComponent(g);
実際はJPanelのさらに上
位の基底クラスまで遡って
処理され、処理の待ち行
列に処理要求が格納され
...と、長くなる.
ここでは、repaint()を呼び
出すと、巡り巡って
paintComponent()が呼び
出されるという理解でよい
32
14
Swingの詳しい使い方

Java API のドキュメントを参照


http://docs.oracle.com/javase/jp/7/technotes/
guides/swing/index.html
そのほかのDemoを参照

追加ファイルのダウンロードが必要
 Java
SDK には含まれない
ので注意
 demo/jfc/SwingSet2/に
サンプルソースあり
33
15