Javaゼミ第11回目 11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス 発表日 6月28日 発表者 加藤 友宏 ランダムアクセスファイル ストリームクラスでは、順次アクセスでファイル内 のデータを読み書きのみ。 RandomAccessFileクラスは、ファイルのどの位 置でもシークでき、その位置でデータの読み書き が可能。 例えば、ファイルに格納されているデータレコード セットを管理するのに使う。 ランダムアクセスファイル RandomAccessFileクラスのコンストラクタ (1) RandomAccessFile(File file, String mode) (2) RandomAccessFile(String name, String mode) (1) fileを読み込み元として、また場合によっては書き込み先とし て、ランダムアクセスファイルストリームを作成する。 (2) nameを持つファイルからの読み込み、およびオプションで書き 込みを行うランダムアクセスファイルストリームを作成する 。 modeは、アクセスモードの指定。以下の4種類がある。 変数 説明 読み込み専用。開いたオブジェクトの任意のwriteメソッドを呼び出すと、 "r" IOException がスローされます。 "rw" 読み込み・書き込み専用。ファイルが存在しない場合は、新規作成する。 "rw" と同様に、読み込み・書き込み専用。ファイルの内容またはメタデータ "rws" を更新したときは、元になる記憶装置にも同時に適用する必要がある。 "rw" と同様に、読み込み・書き込み専用。ファイルの内容を更新したとき "rwd" は、元になる記憶装置にも同時に適用する必要がある。 ランダムアクセスファイル RandomAccessFileは、DataInputインターフェ イスとDataOutputインターフェイスを実装 RandomAccessFileクラスに定義されている主 なインスタンスメソッド メソッド 説明 void close() throws IOException ファイルをクローズする ファイルポインタの現在位置を返す。これ long getFilePointer() throws により、次に読み取るまたは書き込むバ IOException イトの位置を識別する long length() throws ファイル内のバイト数を返す IOException ファイルからバイトを読み取って返す。 int read() throws IOException データが利用可能になるまで待機する。 ランダムアクセスファイル RandomAccessFileクラスに定義されている主 なインスタンスメソッドの続き 説明 ファイルからsizeバイト読み取り、位置indexを先頭 としてbufferに入れる。実際によい取ったバイト数 を返す。データが利用可能になるまで待機する。 ファイルからバイトを読み取り、bufferに入れる。 int read(byte buffer[]) throws 読み取ったバイト数を返す。データが利用可能に IOException なるまで待機する。 ファイルの先頭からnバイトの位置にファイルポイ void seek(long n) throws ンタを位置付ける。この位置で次の読み取りまた IOException は書き込みが発生する。 現在のファイルポインタにnだけ追加して飛ばす。 int skipBytes(int n) throws 実際に飛ばしたバイト数を返す。nが負の場合に IOException はバイトの飛ばしは行われない メソッド int read(byte buffer[], int index, int size) throws IOException ファイルのどの位置にもランダムにアクセスできる → seek()が重要 ランダムアクセスファイルの例 ファイルの最後から指定した個数のバイトを表示するプログラム import java.io.*; // ファイルの長さを決める long position = raf.length(); class Tail { public static void main(String args[]) { try { // RandomAccessFileオブジェクトを //作成する RandomAccessFile raf = new RandomAccessFile(args[0], "r"); // ファイルの終わりに表示する // バイト数を決める long count = Long.valueOf(args[1]).longValue(); // 現在の位置にシークする position -= count; if (position < 0) position = 0; raf.seek(position); // バイトを読み取って、表示する while(true) { // バイトを読み取る try { byte b = raf.readByte(); ランダムアクセスファイルの例 // 文字として表示する System.out.print((char)b); } catch (EOFException eofe) { break; } } } catch (Exception e) { e.printStackTrace(); } } } 実行結果 作成したプログラムの 最後40バイトを指定。 e.printStackTrace(); } } } StreamTokenizerクラス StreamTokenizerクラスは、文字入力ストリーム からデータを解析して、トークンの列を生成。 数字または単語を表す文字のグループ パーサ、コンパイラ、文字入力を処理するプログ ラムで重要な機能 StreamTokenizerクラス StreamTokenizerクラスのコンストラクタ StreamTokenizer(Reader r) rはReaderオブジェクト 4つ定数が定義されている TT_EOF TT_EOL TT_NUMBER TT_WORD ファイルの終わり 行の終わり 数字を読み取ったこと 単語を読み取ったこと StreamTokenizerクラス 3つのインスタンス変数に、重要な情報がある トークンが数字 →nvalに値、ttypeにTT_NUMBER トークンが文字列 →svalに値、ttypeにTT_WORD トークンが数字、文字列以外 → ttypeに読み取った文字 StreamTokenizerクラス StreamTokenizerクラスに定義されているインスタン スメソッド メソッド void commentChar(int ch) 説明 chが単一行コメントから始まることを示す void eollsSignificant(boolean flag) int lineno() flagが真の場合には、行の終わりをトークンとして扱 い、偽の場合は空白として扱う 現在の行番号を返す void lowerCaseMode(boolean flag) flagが真の場合には、トークンを自動的に小文字に 変換し、偽の場合変換しない int nextToken() throws IOException 次のトークンが数字の場合はTT_NUMBERを返し、 次のトークが単語の場合はTT_WORDを返す。それ 以外の場合は、次のトークンに等しい文字を返す void ordinaryChar(int ch) chを通常文字として扱うことを指定する void ordinaryChars(int c1, int c2) 範囲c1~c2(c1およびc2を含む)内のすべての文字 を通常文字として扱うことを指定する StreamTokenizerクラス StreamTokenizerクラスに定義されているインスタ ンスメソッドの続き メソッド void parseNumbers() void pushBack() void quoteChar(int ch) void resetSyntax() 説明 数字を解析することを指定する 現在のトークンを入力ストリームに戻す chを文字列リテラルの引用符文字として定義する すべての文字を通常文字として扱うことを指定する void slashSlashComments(boolean flag) flagが真の場合には、//コメントを無視し、偽の場合 には無視しない void slashStarComments(boolean flag) String toString() void whitespaceChars(int c1, int c2) void wordChars(int c1, int c2) flagが真の場合には、/*...*/コメントを無視し、偽の 場合には無視しない 現在のトークンと等価の文字列を返す 範囲c1~c2(c1およびc2を含む)内のすべての文 字をホワイトスペースとして扱うことを指定する 範囲c1~c2(c1およびc2を含む)内のすべての文 字を単語の文字として扱うことを指定する StreamTokenizerを 使用する手順 1. 2. 3. 4. 5. 6. 7. ReaderのStreamTokenizerオブジェクトを作成 文字を処理する方法を定義 nextToken()を呼び出し次のトークンを取得 ttypeインスタンス変数を読み取り、トークンの方 を判断 sval、nval、ttypeのいずれかのインスタンス変 数からトークンの値を読み取る トークンを処理 nextToken()がStreamTokenizer.TT_EOFを返す までステップ3~6を繰り返す StreamTokenizerクラスの例 テキストファイルを読み取って、その内容を解析するプログラム import java.io.*; class StreamTokenizerDemo { public static void main(String args[]) { try { // FileReaderオブジェクトを作成 FileReader fr = new FileReader(args[0]); // BufferedReaderオブジェクトを作成 BufferedReader br = new BufferedReader(fr); // StreamTokenizerオブジェクトを作成 StreamTokenizer st = new StreamTokenizer(br); // ピリオドを通常文字として定義する st.ordinaryChar('.'); // アポストロフを単語文字として定義する st.wordChars('\'', '\''); // トークンを処理する while(st.nextToken() != StreamTokenizer.TT_EOF) { switch(st.ttype) { case StreamTokenizer.TT_WORD: System.out.println(st.lineno() + ") " + st.sval); break; StreamTokenizerクラスの例 case StreamTokenizer.TT_NUMBER: System.out.println(st.lineno() + ") "+ st.nval); break; default: System.out.println(st.lineno() + ") "+ (char)st.ttype); } } // FileReaderオブジェクトをクローズする fr.close(); } catch (Exception e) { System.out.println("Exception: " + e); } } } StreamTokenizerクラスの例 実行結果 指定したテキストファイルの中身 ファイル名:tokens.txt The price is $23.45 Is that too expensive? (I don't think so) 1) 1) 1) 1) 1) 2) 2) 2) 2) 2) 3) 3) 3) 3) 3) 3) The price is $ 23.45 Is that too expensive ? ( I don't think so ) 練習問題1 RandomAccessFileクラスを用いて、コマンドライン引数か ら取得した文字列をファイルに追加していくプログラムを 作成せよ。 書き込んだ後、ファイルの中身を表示すること。 なお、書き込むファイル名、書き込む内容は任意とする。 実行例 作成したファイルの中身 1行目 2行目 3行目 4行目 5行目 orange strawberry apple banana avocado : : : : : orange strawberry apple banana avocado 練習問題2 コマンドライン引数で取得したファイル名のソースに、 Java のいくつかの予約語が、どのくらいの回数使われて いるのかを調べるプログラムを作成せよ。 調べる予約語は、if,else,try,catch,while,switch,break, continueの8個とする。 実行例 ifが使われた回数は、12回 elseが使われた回数は、10回 tryが使われた回数は、4回 catchが使われた回数は、4回 whileが使われた回数は、4回 switchが使われた回数は、3回 breakが使われた回数は、3回 continueが使われた回数は、3回
© Copyright 2024 ExpyDoc