web-dev-qa-db-ja.com

InputStream、mark()、reset()

mark()メソッドとreset()メソッドは(以下のコードで)正確にどのように機能していますか?私は自分の例を書こうとしましたが、間違ったマーク例外などをスローし始めました。これとの違いが見られないため、このコードにマークとリセットのメソッドを配置する意味がわかりません。

import Java.io.*;

class BufferedInputStreamDemo {
    public static void main(String args[]) {
        String s = "© is a copyright symbol, "
                + "however &copy isn't.\n";
        byte buf[] = s.getBytes();

        ByteArrayInputStream in = new ByteArrayInputStream(buf);
        int c;
        boolean marked = false;

        //try_with_resources
        try (BufferedInputStream f = new BufferedInputStream(in)) {
            while ((c = f.read()) != -1) {
                switch (c) {
                    case '&':
                        if (!marked) {
                            f.mark(32);
                            marked = true;
                        } else {
                            marked = false;
                        }
                        break;
                    case ';':
                        if (marked) {
                            marked = false;
                            System.out.print("(c)");
                        } else
                            System.out.print((char) c);
                        break;
                    case ' ':
                        if (marked) {
                            marked = false;
                            f.reset();
                            System.out.print("&");
                        } else
                            System.out.print((char) c);
                        break;
                    default:
                        if (!marked)
                            System.out.print((char) c);
                        break;
                }
            }
        } catch (IOException e) {
            System.out.println("I/O Error: " + e);
        }
    }
}
12
ashur

f.mark(32);に達すると、読み取りカーソルはすでに_&_の後にあり、resetにマーカーが設定されて、どこにジャンプするかがわかります。したがって、要素を閉じるために_;_が欠落していることを検出した場合は、手動で_&_を印刷し、読み取りカーソルを(マーカーが配置された_&_の後に)移動します。 mark(32) call)、resetメソッドを使用します。次回の読み取りでは、marked変数が設定されていないため、文字が出力されます。

mark(32)は、読み取りカーソルが32文字を超えて進む場合に、マーカーを自動的に削除することを意味します。これは、マーカーがすでに無効化されているため、エラーをトリガーしている他のコードの問題である可能性があります。

7
dan

APIドキュメントを参照してください。

mark(int)

この入力ストリームの現在の位置をマークします。後続のresetメソッドの呼び出しにより、このストリームが最後にマークされた位置に再配置され、後続の読み取りで同じバイトが再読み取りされます。

Readlimit引数は、マーク位置が無効になる前にその数のバイトを読み取ることができるように、この入力ストリームに指示します。

このメソッドは、単にin.mark(readlimit)を実行します。

reset()

このストリームを、この入力ストリームでマークメソッドが最後に呼び出されたときの位置に再配置します。

このメソッドは、単にin.reset()を実行します。

ストリームマークは、ストリームの内容を確認するために少し先読みする必要がある状況で使用することを目的としています。多くの場合、これは一般的なパーサーを呼び出すことで最も簡単に実行できます。ストリームが解析によって処理されるタイプの場合、それはただ楽しく動きます。ストリームがそのタイプでない場合、パーサーは失敗したときに例外をスローする必要があります。これがreadlimitバイト内で発生した場合、外部コードがストリームをリセットして別のパーサーを試すことができます。

5
user647772