入出力

ここでは,java.ioパッケージで最もよく利用されるクラスについて学びます.まず,最初にファイルとディレクトリを扱う方法を学びます.次に,ストリームの作成および使用方法について学びます.

ファイル

Javaにはファイルの入出力を行うのではなく,ファイルそのものを管理するFileクラスが用意されています.Fileクラスは,ファイルまたはディレクトリのプロパティに関する情報をカプセル化します.

Fileクラスのコンストラクタ
File(String path)
File(String directoryPath, String filename)
File(File directory, String filename)

Fileクラスには指定したファイルの状態を参照する多くのメソッドが用意されています.これらのメソッドは例外スローを行わないので,記述も簡単です.

状態参照メソッド
boolean canRead() ファイルが存在し読み取り可能な場合真を返す
boolean canWrite() ファイルが存在し書き込み可能な場合真を返す
boolean exists() ファイルが存在する場合真を返す
String getAbsolutePath() ファイルの絶対パスを返す
String getCanonicalPath() ファイルの標準パスを返す
String getName() ファイルの名前を返す
String getParent() ファイルの親を返す
String getPath() ファイルのパスを返す
boolean isDirectory() ファイルがディレクトリの場合真を返す
boolean isFile() ファイルがディレクトリでない場合真を返す
long length() ファイルのサイズをバイトで返す
long lastModified() 基準時から前回の変更時刻までの時間をミリ秒で返す
String[] list() ディレクトリに入っているファイルの名前を返す

例題 11..1   Fileの管理
\framebox{
\begin{minipage}{13.65cm}
{\rm C:{\small $\yen$}tempにtest.txtファイル作成し,...
...ァイルが存在するか,ファイルのサイズを表示するプログラムを作成しなさい.ただし,ファイル名はコマンドライン引数として入力する.}
\end{minipage}}

import java.io.*;
class FileCondMethod
{
  public static void main(String[] args)
  {
    if(args.length == 0) System.exit(1);
    //ファイルを設定
    File mf = new File(args[0]);
   
    System.out.println("getName = " + mf.getName());
    System.out.println("getPath = " + mf.getPath());
    System.out.println("getParent = " + mf.getParent());
    System.out.println("getAbsolutePath = " + mf.getAbsolutePath());
    System.out.println("canRead = " + mf.canRead());
    System.out.println("exists = " + mf.exists());
    System.out.println("length = " + mf.length());
  }
}

実行結果

\begin{figure}\centering
\includegraphics[width=10.5cm]{JAVAFIG/FileCondMethod.eps}
\end{figure}

Fileクラスにはいくつかの状態変更メソッドが用意されています.これらのメソッドはIOException例外をスローするので,try文で対応する必要があります.

状態変更メソッド
boolean createNewFile() 正しくファイルが作成された場合真を返す
boolean delete() ファイルが正しく削除されたら真を返す
boolean mkdir() ディレクトリが作成されたら真を返す
boolean mkdirs() ディレクトリが作成されたら真を返す
boolean renameTo(File newName) ファイル名を変更が正しくできたら真を返す

例題 11..2   Fileクラス
\framebox{
\begin{minipage}{13.65cm}
{\rm C:{\small $\yen$}tempにtest.txtファイル作成し,...
...イルを作成し,新規作成ができたか確認する.また,ファイル名を変更し,元のファイルが存在するか確認するプログラムを作成しなさい.}
\end{minipage}}

import java.io.*;
class FileChangeMethod {
  public static void main(String[] args)
  {
    if(args.length == 0) System.exit(1);
    try
    {
    //ファイルを設定
      File mf = new File(args[0]);
      File mff = new File("mff.txt");
     
      System.out.println("exists(mf) = " + mf.exists());
      System.out.println("createNewFile = " + mf.createNewFile());
      System.out.println("exists(mf) = " + mf.exists());
      System.out.println("renameTo = " + mf.renameTo(mff));
      System.out.println("exists(mf) = " + mf.exists());
      System.out.println("exists(mff) = " + mff.exists());
    }
    catch(IOException ex)
    {
      System.out.println("err: " + ex);
    }
  }
}

実行結果

\begin{figure}\centering
\includegraphics[width=10.5cm]{JAVAFIG/FileCondMethod.eps}
\end{figure}

ストリーム

プログラムでは,データの入力や出力という処理がよく用いられます.このデータの入出力をJavaではストリーム(stream)という概念で操作します.ストリームは入出力先を読み書き可能な状態に設定し,実際の読み書きを行い,その後閉じます.また,必要に応じて読み書き位置にマークしたり,書き込み中のデータを強制出力したりすることもできます.

実際にストリームを用いるときには,入力用または出力用ストリームのオブジェクトを宣言することで,論理デバイスとと物理デバイスを結び付けます.あとは,ユーザはストリームオブジェクトを使用することで,簡単にデータの入出力をすることができるようになります.

ストリームには,文字ストリームバイトストリームの2つのタイプがあります.バイトストリームでは,バイナリデータの読み取りおよび書き込むをおこなうことができます.文字ストリームでは,文字および文字列の読み取りおよび書き込むを行うことができます.入力文字ストリームはバイトを文字に変換し,出力ストリームは文字をバイトに変換します.

Javaでは,内部で文字を16ビットのUnicodeエンコーディングに従ってあらわします.ただし,このエンコーディングはマシンで使用されているエンコーディングと異なる場合があります.文字ストリームは,これらの2つのエンコーディング間で変換を行います.

文字ストリーム
Reader Writer
入力系の抽象基本クラス 出力系の抽象基本クラス
BufferedReader BufferedWrite
バッファ付文字入力 バッファ付文字出力
InputStreamReader OutputStreamWriter
バイト入力を文字に変換 文字をバイト出力に変換
FileReader FileWriter
ファイルからの文字入力 ファイルへの文字出力
  PrintWriter
  型を持つデータの出力

バッファなし文字ストリーム

バッファなし文字ストリームは,FileWriterクラスとFileReaderクラスを用いて行います.ファイル名を指定してインスタンスを生成するには,次の記述を行います.

書き込みファイル指定
FileWriter fw = new FileWriter("test.txt");

読み込みファイル指定
FileReader fr = new FileReader("test.txt");

これでファイルがオープンし,入出力の準備ができたことになります.このようにしてオープンしたファイルに対して,入出力処理を行います..処理が終了したら,fw.close();とfr.close();でファイルを閉じます.

データの読み込みを行うには,次のReaderクラスのインスタンスメソッドを用います.

Readerクラスのインスタンスメソッド
void close() 入力ストリームを閉じる
int read() ストリームから1文字を読み取る
int read(char[] buffer) bufferにbuffer.length文字まで読み取る
  ことを試みる.
int read(char[] buffer,int offset, int numChars) buffer[offset]を先頭として,
  bufferにbuffer.length文字まで読み取る

データの書き込みを行うには,次のWriterクラスのインスタンスメソッドを用います.

Readerクラスのインスタンスメソッド
void close() 出力ストリームを閉じる
void write(int c) ストリームにcの下位16ビットを書き込む
void write(char[] buffer) ストリームにbuffer内の文字を書き込む
void write(char[] buffer,int offset, int numChars) buffer[offset]を先頭として,
  bufferにbuffer.length文字まで書き込む
void write(String s) ストリームにsを書き込む
void write(String sm int index, int size) ストリームに位置indexを先頭として
  s内のsize文字を書き込む

例題 11..3   バッファなしファイル入出力
\framebox{
\begin{minipage}{13.65cm}
{\rm 書き込みファイルを''test1.txt''とし,文字列''abcde''を書き込み,その後,書き込んだ文字列を読み取り表示し,ファイルを閉じるプログラムを作成しなさい.}
\end{minipage}}

import java.io.*;
class FileIO
{
  public static void main(String[] args)
  {
    String str = "abcde";
    try
    {
      //FileWriterオブジェクトの作成
      FileWriter fw = new FileWriter("test1.txt");
      //ファイルに文字列を書き込む
      fw.write(str);
      fw.write("\r\n");
      //FileWriterオブジェクトを閉じる
      fw.close();
    }
    catch(Exception ex)
    {
      System.out.println("Exception: " + ex);
    }
    try
    {
      //FileReaderオブジェクトの作成
      FileReader fr = new FileReader("test1.txt");
      //文字を読み取って表示
      int i;
      while((i = fr.read()) != -1)
      {
        System.out.print((char)i);
      }
      //FileReaderオブジェクトを閉じる
      fr.close();
    }
    catch(Exception ex)
    {
      System.out.println("Exception: "+ ex);
    }
  }
}\\

実行結果

\begin{figure}\centering
\includegraphics[width=7.8cm]{JAVAFIG/FileIO.eps}
\end{figure}

バッファあり文字ストリーム

バッファあり文字ストリームは,BufferedWriterクラスとBufferedReaderクラスを用いて行います.バッファリングの利点は,物理デバイスへの読み取りおよび書き込みの回数を減らすことができるところです.ファイル名を指定してインスタンスを生成し,それをバッファリング可能にする標準的な方法は次の通りです.

書き込みファイル指定
BufferedWriter bw = new BufferedWriter(new FileWriter("test1.txt"));

読み込みファイル指定
BufferedReader br = new BufferedReader(new FileReader("test.txt"));

これでファイルがオープンし,入出力の準備ができたことになります.このようにしてオープンしたファイルに対して,入出力処理を行います.処理が終了したら,bw.close();とbr.close();でファイルを閉じます.

データの読み込みを行うには,Readerクラスのインスタンスメソッドに加え,文字ストリームから改行終端文字列を読み取るreadLine()メソッドを用います.

データの書き込みを行うには,Writerクラスのインスタンスメソッドを用います.

例題 11..4   バッファありファイル入出力
\framebox{
\begin{minipage}{13.65cm}
{\rm 書き込みファイルを''test1.txt''とし,文字列''abcde''を書き込み,その後,書き込んだ文字列を読み取り表示し,ファイルを閉じるプログラムを作成しなさい.}
\end{minipage}}

import java.io.*;
class FileIO
{
  public static void main(String[] args)
  {
    String str = "abcde";
    try
    {
      //BufferedWriterオブジェクトの作成
      BufferedWriter bw = new BufferedWriter(new FileWriter("test1.txt"));
      //ファイルに文字列を書き込む
      bw.write(str);
      bw.write("\r\n");
      //BufferedWriterオブジェクトを閉じる
      bw.close();
    }
    catch(Exception ex)
    {
      System.out.println("Exception: " + ex);
    }
    try
    {
      //BufferedReaderオブジェクトの作成
      BufferedReader br = new BufferedReader(new FileReader("test1.txt"));
      //文字を読み取って表示
      String s;
      while((s = br.readLine()) != null)
      {
        System.out.print((char)i);
      }
      //BufferedReaderオブジェクトを閉じる
      br.close();
    }
    catch(Exception ex)
    {
      System.out.println("Exception: "+ ex);
    }
  }
}\\

実行結果

\begin{figure}\centering
\includegraphics[width=7.8cm]{JAVAFIG/BufferedFileIO.eps}
\end{figure}

バイトストリーム
InputStream OutputStream
バイト入力用基本クラス バイト出力用基本クラス
FileInputStream FileOutputStream
ファイルからのバイト入力 ファイルへのバイト出力
FilterInputStream FilterOutputStream
入力をフィルタに通す 出力をフィルタに通す
BufferedInputStream BufferedOutputStream
入力をバッファに読み込む 出力をバッファに入れる
DataInputStream DataOutputStream
入力を基本データ型に解釈 基本データ型を出力
  PrintStream
  文字と型データの出力