JAva基礎復習(18)-オブジェクトシーケンス化
2009年8月3日月曜日00時03分対象のシーケンス化の深い探究同級生の疑問について、私はjdkの実現を研究して、あなたに役に立つことを望んで、研究状況は以下の通りです:私の本機でコードをテストして、シーケンス化のファイルguo.txtを見て、ultraEditの下で、本地でコードをコードして見るのは一連の乱符号で、しかし16進数で見て、規則を発見することができて、ファイルの内容は以下の通りです.AC ED 00 05 7 A 00 02 FD 11 00 A 0 D 00 A 07…(後述省略)実行するたびに、前のAC ED 00 05が常に存在することがわかります.まずこれを説明しましょう.オブジェクト出力ストリームを作成するときに、コンストラクタを表示するコードは次のとおりです.
writeStreamHeader();//ファイルに対してオブジェクト出力ストリームを開くと、4バイトのコンテンツが書き込まれます.書き込みを表示できる内容は次のとおりです.
書き込みの2つの定数は、インタフェースObjectStreamConstantsで次のように定義されます.
注釈から分かるように、ACEDはシーケンス化ファイルに書き込まれた固定タグにすぎず、識別の役割を果たす.BlockDataOutputStreamクラスのwriteShortメソッドは内部でBitsクラスのメソッドも使用されており、具体的に興味のある方は自分でソースコードを見ることができます.shortと書かれておりjavaではshortが2バイトを占めるため、ファイルヘッダはAC ED 00 05となっている.そして7 Aを説明する.実際には、比較的少ないデータをテストする場合、書き込まれたデータの長さが255個未満の場合、ファイルの前の部分には、AC ED 00 05 77 05 01 10 13 0 A 06 boutがOjbectOutStreamのプライベート静的内部クラスBlockDataOutputStreamの例であるという別の結果があります.クラス保有
apiにも明記されており、以下に抜粋します. 基本データ(serializableフィールドおよびexternalizableデータを除く)は、ObjectOutputStreamにブロックデータ記録として書き込まれる.ブロックデータ記録はヘッダとデータからなる.ブロックデータ部分には、タグと、部分の後に続くバイト数が含まれます.連続した基本書き込みデータは、1つのブロックデータレコードに統合される.ブロックデータレコードのブロック係数は1024バイトである.各ブロック・データ・レコードは1024バイトを満たすか、ブロック・データ・モードの終了時に書き込まれる.ソースコードは次のとおりです.
以上のコードのTC_BLOCKDATAもインタフェースObjectStreamConstantsに定義されています.
ブロックバッファが満杯になるたびに(1024より大きい)バッファがリフレッシュされ、ブロックとデータがファイルに書き込まれて保存されるので、保存されているデータが多い場合、ファイルの後ろの部分にも77 xxまたは7 A xxが複数回表示され、それは複数回の書き込みによるものであることがわかります.バッファをリフレッシュするたびに、ブロックバッファbufオフセットposを0にリセットし、最初から書き込みます.データ長はこの文コードで生成されます Bits.putInt(hbuf, 1, len); クラスBitsのこのメソッドを引き続き表示します.
この方法は皆さんが理解できると信じていますが、実は長さ(int)のバイトごとにhbufに取り出して7 Aと一緒に頭を作ります.もう1つは、出力ストリームのwriteメソッドを呼び出しても出力ストリームをオフにしない場合、データ量が1024バイト未満の場合、ファイルにはシリアル化されたファイルヘッダ:AC ED 005しか含まれず、他のデータは実際に書き込まれません.データ量が1024バイト以上の場合、容量を超えるとバッファがリフレッシュされるので、ファイルにはもちろんデータが含まれます.したがって、少ないデータを書き込むときは、出力ストリームを閉じることに注意し、閉じるときにバッファのデータをファイルに書き込むことができます.一部の非キーコードは貼られていないので、研究したい学生は直接確認すればいいです.以上の内容は、ソースコードとテストを組み合わせた本人の結論にすぎません.不足点は、ご批判ください.オブジェクトのシーケンス化に対して、シーケンス化されたクラスとフィールドの基本情報はシーケンス化ファイルに保存されます.逆シーケンス化は常に一定の情報に依存していることが考えられます.普通のテキストファイルに対して直接逆シーケンス化することはできません.これでは考えられません.ほほほ.また、まず、ファイルヘッダ(すなわち、AC ED 00 05)に基づいて、シーケンス化されたファイルであるか否かを判定し、そうでなければ異常を直接投げ出す.オブジェクトのシーケンス化の問題について、シーケンス化したいクラスがSerialiazbleインタフェースを実装した場合、シーケンス化後に再び逆シーケンス化すると、クラスのデフォルトコンストラクタは呼び出されません.クラスがExternalizableインタフェースを実装している場合、逆シーケンス化によってインスタンスが生成されると、デフォルトのコンストラクタが呼び出され、メンバー変数が初期化されます.
public ObjectOutputStream(OutputStream out) throws IOException {
verifySubclass();
bout = new BlockDataOutputStream(out);
handles = new HandleTable(10, (float) 3.00);
subs = new ReplaceTable(10, (float) 3.00);
enableOverride = false;
writeStreamHeader();
bout.setBlockDataMode(true);
if (extendedDebugInfo) {
debugInfoStack = new DebugTraceInfoStack();
} else {
debugInfoStack = null;
}
}
writeStreamHeader();//ファイルに対してオブジェクト出力ストリームを開くと、4バイトのコンテンツが書き込まれます.書き込みを表示できる内容は次のとおりです.
protected void writeStreamHeader() throws IOException {
bout.writeShort(STREAM_MAGIC);
bout.writeShort(STREAM_VERSION);
}
書き込みの2つの定数は、インタフェースObjectStreamConstantsで次のように定義されます.
public interface ObjectStreamConstants {
/**
* Magic number that is written to the stream header.
*/
final static short STREAM_MAGIC = (short)0xaced;
/**
* Version number that is written to the stream header.
*/
final static short STREAM_VERSION = 5;
注釈から分かるように、ACEDはシーケンス化ファイルに書き込まれた固定タグにすぎず、識別の役割を果たす.BlockDataOutputStreamクラスのwriteShortメソッドは内部でBitsクラスのメソッドも使用されており、具体的に興味のある方は自分でソースコードを見ることができます.shortと書かれておりjavaではshortが2バイトを占めるため、ファイルヘッダはAC ED 00 05となっている.そして7 Aを説明する.実際には、比較的少ないデータをテストする場合、書き込まれたデータの長さが255個未満の場合、ファイルの前の部分には、AC ED 00 05 77 05 01 10 13 0 A 06 boutがOjbectOutStreamのプライベート静的内部クラスBlockDataOutputStreamの例であるという別の結果があります.クラス保有
/** buffer for writing block data headers */
private final byte[] hbuf = new byte[MAX_HEADER_SIZE];//
/** buffer for writing general/block data */
private final byte[] buf = new byte[MAX_BLOCK_SIZE];// , MAX_BLOCK_SIZE(1024) , 。
apiにも明記されており、以下に抜粋します. 基本データ(serializableフィールドおよびexternalizableデータを除く)は、ObjectOutputStreamにブロックデータ記録として書き込まれる.ブロックデータ記録はヘッダとデータからなる.ブロックデータ部分には、タグと、部分の後に続くバイト数が含まれます.連続した基本書き込みデータは、1つのブロックデータレコードに統合される.ブロックデータレコードのブロック係数は1024バイトである.各ブロック・データ・レコードは1024バイトを満たすか、ブロック・データ・モードの終了時に書き込まれる.ソースコードは次のとおりです.
private void writeBlockHeader(int len) throws IOException {
if (len <= 0xFF) {
hbuf[0] = TC_BLOCKDATA;
hbuf[1] = (byte) len;
out.write(hbuf, 0, 2);
} else {
hbuf[0] = TC_BLOCKDATALONG;
Bits.putInt(hbuf, 1, len);
out.write(hbuf, 0, 5);
}
}
以上のコードのTC_BLOCKDATAもインタフェースObjectStreamConstantsに定義されています.
/**
* Block of optional data. Byte following tag indicates number
* of bytes in this block data.
*/
final static byte TC_BLOCKDATA =(byte)0x77;// 77 , 5 , , 255 , hbuf[1] = (byte) len; 。
/**
* long Block data. The long following the tag indicates the
* number of bytes in this block data.
*/
final static byte TC_BLOCKDATALONG= (byte)0x7A;//
ブロックバッファが満杯になるたびに(1024より大きい)バッファがリフレッシュされ、ブロックとデータがファイルに書き込まれて保存されるので、保存されているデータが多い場合、ファイルの後ろの部分にも77 xxまたは7 A xxが複数回表示され、それは複数回の書き込みによるものであることがわかります.バッファをリフレッシュするたびに、ブロックバッファbufオフセットposを0にリセットし、最初から書き込みます.データ長はこの文コードで生成されます Bits.putInt(hbuf, 1, len); クラスBitsのこのメソッドを引き続き表示します.
static void putInt(byte[] b, int off, int val) {
b[off + 3] = (byte) (val >>> 0);
b[off + 2] = (byte) (val >>> 8);
b[off + 1] = (byte) (val >>> 16);
b[off + 0] = (byte) (val >>> 24);
}
この方法は皆さんが理解できると信じていますが、実は長さ(int)のバイトごとにhbufに取り出して7 Aと一緒に頭を作ります.もう1つは、出力ストリームのwriteメソッドを呼び出しても出力ストリームをオフにしない場合、データ量が1024バイト未満の場合、ファイルにはシリアル化されたファイルヘッダ:AC ED 005しか含まれず、他のデータは実際に書き込まれません.データ量が1024バイト以上の場合、容量を超えるとバッファがリフレッシュされるので、ファイルにはもちろんデータが含まれます.したがって、少ないデータを書き込むときは、出力ストリームを閉じることに注意し、閉じるときにバッファのデータをファイルに書き込むことができます.一部の非キーコードは貼られていないので、研究したい学生は直接確認すればいいです.以上の内容は、ソースコードとテストを組み合わせた本人の結論にすぎません.不足点は、ご批判ください.オブジェクトのシーケンス化に対して、シーケンス化されたクラスとフィールドの基本情報はシーケンス化ファイルに保存されます.逆シーケンス化は常に一定の情報に依存していることが考えられます.普通のテキストファイルに対して直接逆シーケンス化することはできません.これでは考えられません.ほほほ.また、まず、ファイルヘッダ(すなわち、AC ED 00 05)に基づいて、シーケンス化されたファイルであるか否かを判定し、そうでなければ異常を直接投げ出す.オブジェクトのシーケンス化の問題について、シーケンス化したいクラスがSerialiazbleインタフェースを実装した場合、シーケンス化後に再び逆シーケンス化すると、クラスのデフォルトコンストラクタは呼び出されません.クラスがExternalizableインタフェースを実装している場合、逆シーケンス化によってインスタンスが生成されると、デフォルトのコンストラクタが呼び出され、メンバー変数が初期化されます.