1

私たちのアプリケーションには、次のコードに還元できる問題があります。

public static void main(String[] args) throws IOException, ClassNotFoundException {
        File tempFile = File.createTempFile("teststream", "");
        FileOutputStream fos = new FileOutputStream(tempFile);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeInt(1);
        oos.writeObject("foo");
        oos.writeInt(2);
        oos.flush();
        oos.close();
        FileInputStream fis = new FileInputStream(tempFile);
        ObjectInputStream ois = new ObjectInputStream(fis);
        int n1 = ois.readInt();
        Object o1 = ois.readObject();
        int n2 = ois.readInt();
    }

このコードは機能しますが、次の行にコメントを付けると:

Object o1 = ois.readObject();

次の行

int n2 = ois.readInt();

EOFExceptionオブジェクトと整数を書き込んだため、ファイルにデータがありますが、がスローされます。readIntのjavadoc は、この動作を示していません。これについては少し心配です。コードで実際のファイルの例外と間違ったタイプのコンテンツEOFExceptionを区別したいからです。

例外のスタック トレースは次のとおりです。

Exception in thread "main" java.io.EOFException
    at java.io.DataInputStream.readInt(DataInputStream.java:392)
    at java.io.ObjectInputStream$BlockDataInputStream.readInt(ObjectInputStream.java:2793)
    at java.io.ObjectInputStream.readInt(ObjectInputStream.java:968)

これは、次のコードがDataInputStream例外をスローすることを意味します。

 public final int readInt() throws IOException {
        int ch1 = in.read();
        int ch2 = in.read();
        int ch3 = in.read();
        int ch4 = in.read();
        if ((ch1 | ch2 | ch3 | ch4) < 0)
            throw new EOFException();

しかしin.read()、入力ストリームにデータがある場合に負の数を返すことは想定されていないので、私は本当に興味をそそられます。

readIndこれが起こらないようにするために私のコードでできることはありますwriteObjectか?

私はこのバージョンのJavaを使用しています:

java version "1.7.0_07"
OpenJDK Runtime Environment (IcedTea7 2.3.2) (ArchLinux build 7.u7_2.3.2-2-x86_64)
OpenJDK 64-Bit Server VM (build 23.2-b09, mixed mode)
4

3 に答える 3

5

基になるストリームは、ブロック ヘッダーを使用してブロックで記述されます。readIntオブジェクトが書き込まれたときにしようとすると、間違ったブロック タイプが見つかり、 in.read()-1 が返されます。

次のメソッドが呼び出されます。

    /**
     * Attempts to read in the next block data header (if any).  If
     * canBlock is false and a full header cannot be read without possibly
     * blocking, returns HEADER_BLOCKED, else if the next element in the
     * stream is a block data header, returns the block data length
     * specified by the header, else returns -1.
     */
    private int readBlockHeader(boolean canBlock) throws IOException {
         // code deleted
                int tc = in.peek();
                switch (tc) {
                    case TC_BLOCKDATA:
         // code deleted
                    default:
                        if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) {
                            throw new StreamCorruptedException(
                                String.format("invalid type code: %02X",
                                tc));
                        }
                        return -1;
    }

-1 は、StreamCorruptedExceptionここでは a の方が適切な選択であった可能性がある場合に、最後に到達したことを意味します。

于 2012-09-26T09:49:12.887 に答える
1

の行にコメントを付けObject o1 = ois.readObject();てプログラムを実行すると、n2intではなく、シリアル化されたオブジェクトから 4 文字を読み取っています。はい、オブジェクトがどのようにシリアル化されたかによっては、負の値を取得できます (たとえば、格納されたオブジェクトのエンディアン。メモリが正しく機能する場合、ビッグエンディアンで格納されます)。

于 2012-09-26T09:12:36.133 に答える
1

状況は完全に無効です。あなたが書いたものを読まなければ、振る舞いは未定義です。この状況ではおそらくスローすべきEOFExceptionではありませんが、間違ったことをしたときに何をすべきかを示す仕様を指摘できないため、実際に立つ足がありません.

于 2012-09-27T00:50:19.773 に答える