JDK

java.io.StringReaderクラス

StringReaderクラスはStringをストリームのように扱うためのクラスである。

インスタンス変数として,次の4つが定義されている。strは読み込む対象の文字列である。lengthはstrの長さを示す。nextは次に読み込む位置を表すインデックスである。markはreset()メソッドを実行した際に戻るべき位置のインデックスを表す。
  • String str
  • int length
  • int next
  • int mark

コンストラクタはStringReader(String s)のみが定義されており,引数に読み込む対象の文字列を渡す。

read()メソッドは対象文字列からnext変数で示された位置のバイトを読込み,int型に格納して返す。そして,next変数を1増加させる。read(char cbuf[], int off, int len)read()メソッドは対象文字列から指定のオフセットと長さだけ読込み,byte[]型の引数bufに格納して返す。skip(long)メソッドは指定されたバイト数だけ読み込む位置をスキップする。mark(int readAheadLimit)メソッドは,指定の位置にマークを設定し,reset()メソッドが呼ばれた際に戻る位置を設定する。reset()メソッドでは,next変数にmark変数の内容を設定し,markの位置から読み込むように状態を変化させる。close()メソッドは,インスタンス変数strにnullをセットしているだけである。

/*
 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package java.io;
public class StringReader extends Reader {
    private String str;
    private int length;
    private int next = 0;
    private int mark = 0;
    public StringReader(String s) {
        this.str = s;
        this.length = s.length();
    }
    private void ensureOpen() throws IOException {
        if (str == null)
            throw new IOException("Stream closed");
    }
    public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (next >= length)
                return -1;
            return str.charAt(next++);
        }
    }
    public int read(char cbuf[], int off, int len) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
                ((off + len) > cbuf.length) || ((off + len) < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
            if (next >= length)
                return -1;
            int n = Math.min(length – next, len);
            str.getChars(next, next + n, cbuf, off);
            next += n;
            return n;
        }
    }
    public long skip(long ns) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (next >= length)
                return 0;
            // Bound skip by beginning and end of the source
            long n = Math.min(length – next, ns);
            n = Math.max(-next, n);
            next += n;
            return n;
        }
    }
    public boolean ready() throws IOException {
        synchronized (lock) {
            ensureOpen();
            return true;
        }
    }
    public boolean markSupported() {
        return true;
    }
    public void mark(int readAheadLimit) throws IOException {
        if (readAheadLimit < 0){
            throw new IllegalArgumentException("Read-ahead limit < 0");
        }
        synchronized (lock) {
            ensureOpen();
            mark = next;
        }
    }
    public void reset() throws IOException {
        synchronized (lock) {
            ensureOpen();
            next = mark;
        }
    }
    public void close() {
        synchronized (lock) {
            str = null;
        }
    }
}