ObjectOutputStream objectOutputStream = null; try { objectOutputStream = new ObjectOutputStream(outFile); } catch (IOException e) { e.printStackTrace(); } PersonX person = new PersonX("donald", 27, "man"); try { objectOutputStream.writeObject(person); objectOutputStream.writeInt(4); objectOutputStream.writeUTF("it is a man"); objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); }
序列化的关键在这几句
objectOutputStream = new ObjectOutputStream(outFile); objectOutputStream.writeObject(person); objectOutputStream.writeInt(4); objectOutputStream.writeUTF("it is a man");
我们一句一句的分析,先看构造ObjectOutputStream
public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants { /** filter stream for handling block data conversion */ private final BlockDataOutputStream bout;//对象数据输出流 /** stream protocol version */ private int protocol = PROTOCOL_VERSION_2; ** buffer for writing primitive field values */ private byte[] primVals; /** if true, invoke writeObjectOverride() instead of writeObject() */ private final boolean enableOverride; }
先看构造
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; } } /** * The writeStreamHeader method is provided so subclasses can append or * prepend their own header to the stream. It writes the magic number and * version to the stream. *写流版本号和流魔数 * @throws IOException if I/O errors occur while writing to the underlying * stream */ protected void writeStreamHeader() throws IOException { bout.writeShort(STREAM_MAGIC); bout.writeShort(STREAM_VERSION); }
private static class BlockDataOutputStream extends OutputStream implements DataOutput { /** maximum data block length */ private static final int MAX_BLOCK_SIZE = 1024; /** maximum data block header length */ private static final int MAX_HEADER_SIZE = 5; /** (tunable) length of char buffer (for writing strings) */ private static final int CHAR_BUF_SIZE = 256;
/** buffer for writing general/block data ,存放对象序列化数据*/ private final byte[] buf = new byte[MAX_BLOCK_SIZE]; /** buffer for writing block data headers,存放数据头部 */ private final byte[] hbuf = new byte[MAX_HEADER_SIZE]; /** char buffer for fast string writes ,这个用于直接写原始类型*/ private final char[] cbuf = new char[CHAR_BUF_SIZE];
/** block data mode */ private boolean blkmode = false; /** current offset into buf */ private int pos = 0;
/** underlying output stream */ private final OutputStream out; /** loopback stream (for data writes that span data blocks),写原始数据的输出流 */ private final DataOutputStream dout;
/** * Creates new BlockDataOutputStream on top of given underlying stream. * Block data mode is turned off by default. */ BlockDataOutputStream(OutputStream out) { this.out = out; dout = new DataOutputStream(this); }
public class DataOutputStream extends FilterOutputStream implements DataOutput { /** * The number of bytes written to the data output stream so far. * If this counter overflows, it will be wrapped to Integer.MAX_VALUE. */ protected int written;
/** * bytearr is initialized on demand by writeUTF */ private byte[] bytearr = null;
/** * Creates a new data output stream to write data to the specified * underlying output stream. The counter written is * set to zero. * * @param out the underlying output stream, to be saved for later * use. * @see java.io.FilterOutputStream#out */ public DataOutputStream(OutputStream out) { super(out); }
public class ObjectStreamClass implements Serializable {
/** serialPersistentFields value indicating no serializable fields */ //序列化对象属相描述 public static final ObjectStreamField[] NO_FIELDS = new ObjectStreamField[0]; /** reflection factory for obtaining serialization constructors */ private static final ReflectionFactory reflFactory = AccessController.doPrivileged( new ReflectionFactory.GetReflectionFactoryAction()); private static class Caches { /** cache mapping local classes -> descriptors,类描述缓存 */ static final ConcurrentMap> localDescs = new ConcurrentHashMap<>();
/** cache mapping field group/local desc pairs -> field reflectors */ static final ConcurrentMap> reflectors = new ConcurrentHashMap<>();
/** queue for WeakReferences to local classes */ private static final ReferenceQueue> localDescsQueue = new ReferenceQueue<>(); /** queue for WeakReferences to field reflectors keys */ private static final ReferenceQueue> reflectorsQueue = new ReferenceQueue<>(); } /** class associated with this descriptor (if any) */ private Class> cl; /** name of class represented by this descriptor */ private String name; /** serialVersionUID of represented class (null if not computed yet) */ private volatile Long suid;
/** true if represents dynamic proxy class */ private boolean isProxy; /** true if represents enum type */ private boolean isEnum; /** true if represented class implements Serializable */ private boolean serializable; /** true if represented class implements Externalizable */ private boolean externalizable; /** true if desc has data written by class-defined writeObject method */ private boolean hasWriteObjectData; /** exception (if any) thrown while attempting to resolve class */ private ClassNotFoundException resolveEx; /** exception (if any) to throw if non-enum deserialization attempted */ private ExceptionInfo deserializeEx; /** exception (if any) to throw if non-enum serialization attempted */ private ExceptionInfo serializeEx; /** exception (if any) to throw if default serialization attempted */ private ExceptionInfo defaultSerializeEx;
/** serializable fields */ private ObjectStreamField[] fields; /** aggregate marshalled size of primitive fields */ private int primDataSize; /** number of non-primitive fields */ private int numObjFields; /** reflector for setting/getting serializable field values */ private FieldReflector fieldRefl; /** data layout of serialized objects described by this class desc */ private volatile ClassDataSlot[] dataLayout;
/** serialization-appropriate constructor, or null if none */ private Constructor cons; /** class-defined writeObject method, or null if none */ private Method writeObjectMethod; /** class-defined readObject method, or null if none */ private Method readObjectMethod; /** class-defined readObjectNoData method, or null if none */ private Method readObjectNoDataMethod; /** class-defined writeReplace method, or null if none */ private Method writeReplaceMethod; /** class-defined readResolve method, or null if none */ private Method readResolveMethod; }
回到这一句:
ObjectStreamClass.lookup(cl, true)
static ObjectStreamClass lookup(Class> cl, boolean all) { if (!(all || Serializable.class.isAssignableFrom(cl))) { return null; } //从缓存中获取对象流描述 processQueue(Caches.localDescsQueue, Caches.localDescs); WeakClassKey key = new WeakClassKey(cl, Caches.localDescsQueue); Reference> ref = Caches.localDescs.get(key); ... if (entry == null) { try { //没有则,创建一个流对象 entry = new ObjectStreamClass(cl); } catch (Throwable th) { entry = th; } if (future.set(entry)) { Caches.localDescs.put(key, new SoftReference
//写非代理对象描述 /* Writes class descriptor representing a standard (i.e., not a dynamic * proxy) class to stream. */ private void writeNonProxyDesc(ObjectStreamClass desc, boolean unshared) throws IOException { bout.writeByte(TC_CLASSDESC); handles.assign(unshared ? null : desc);
if (protocol == PROTOCOL_VERSION_1) { // do not invoke class descriptor write hook with old protocol desc.writeNonProxy(this); } else { //从前面可以看出,协议版本为PROTOCOL_VERSION_2 writeClassDescriptor(desc); }
/** * Fetches the serializable object field values of object obj and stores * them in array vals starting at offset 0. It is the responsibility of * the caller to ensure that obj is of the proper type if non-null. */ void getObjFieldValues(Object obj, Object[] vals) { //** reflector for setting/getting serializable field values */ //private FieldReflector fieldRefl; //属性对应的set&get方法反射器 fieldRefl.getObjFieldValues(obj, vals); }
/** * Fetches the serializable object field values of object obj and * stores them in array vals starting at offset 0. The caller is * responsible for ensuring that obj is of the proper type. */ void getObjFieldValues(Object obj, Object[] vals) { if (obj == null) { throw new NullPointerException(); } /* assuming checkDefaultSerialize() has been called on the class * descriptor this FieldReflector was obtained from, no field keys * in array should be equal to Unsafe.INVALID_FIELD_OFFSET. */ for (int i = numPrimFields; i < fields.length; i++) { switch (typeCodes[i]) { case 'L': case '[': vals[offsets[i]] = unsafe.getObject(obj, readKeys[i]); break;
default: throw new InternalError(); } } }
//FieldReflector
private static class FieldReflector {
/** handle for performing unsafe operations */ private static final Unsafe unsafe = Unsafe.getUnsafe();
/** fields to operate on */ private final ObjectStreamField[] fields; /** number of primitive fields */ private final int numPrimFields; /** unsafe field keys for reading fields - may contain dupes */ private final long[] readKeys; /** unsafe fields keys for writing fields - no dupes */ private final long[] writeKeys; /** field data offsets */ private final int[] offsets; /** field type codes */ private final char[] typeCodes; /** field types */ private final Class>[] types; }
public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants { /** filter stream for handling block data conversion */ private final BlockDataInputStream bin; /** validation callback list */ private final ValidationList vlist; /** recursion depth */ private int depth; /** whether stream is closed */ private boolean closed;
/** wire handle -> obj/exception map */ private final HandleTable handles; /** scratch field for passing handle values up/down call stack */ private int passHandle = NULL_HANDLE; /** flag set when at end of field value block with no TC_ENDBLOCKDATA */ private boolean defaultDataEnd = false;
/** buffer for reading primitive field values */ private byte[] primVals;
/** if true, invoke readObjectOverride() instead of readObject() */ private final boolean enableOverride; /** if true, invoke resolveObject() */ private boolean enableResolve;
/** * Context during upcalls to class-defined readObject methods; holds * object currently being deserialized and descriptor for current class. * Null when not during readObject upcall. */ private SerialCallbackContext curContext;
}
// BlockDataInputStream
private class BlockDataInputStream extends InputStream implements DataInput { /** maximum data block length */ private static final int MAX_BLOCK_SIZE = 1024; /** maximum data block header length */ private static final int MAX_HEADER_SIZE = 5; /** (tunable) length of char buffer (for reading strings) */ private static final int CHAR_BUF_SIZE = 256; /** readBlockHeader() return value indicating header read may block */ private static final int HEADER_BLOCKED = -2;
/** buffer for reading general/block data */ private final byte[] buf = new byte[MAX_BLOCK_SIZE]; /** buffer for reading block data headers */ private final byte[] hbuf = new byte[MAX_HEADER_SIZE]; /** char buffer for fast string reads */ private final char[] cbuf = new char[CHAR_BUF_SIZE];
/** block data mode */ private boolean blkmode = false;
// block data state fields; values meaningful only when blkmode true /** current offset into buf */ private int pos = 0; /** end offset of valid data in buf, or -1 if no more block data */ private int end = -1; /** number of bytes in current block yet to be read from stream */ private int unread = 0;
/** underlying stream (wrapped in peekable filter stream) */ private final PeekInputStream in; /** loopback stream (for data reads that span data blocks) */ private final DataInputStream din;
/** * Creates new BlockDataInputStream on top of given underlying stream. * Block data mode is turned off by default. */ BlockDataInputStream(InputStream in) { this.in = new PeekInputStream(in); din = new DataInputStream(this); } }
/** underlying stream */ private final InputStream in; /** peeked byte */ private int peekb = -1;
/** * Creates new PeekInputStream on top of given underlying stream. */ PeekInputStream(InputStream in) { this.in = in; }
/** * Peeks at next byte value in stream. Similar to read(), except * that it does not consume the read value. */ int peek() throws IOException { return (peekb >= 0) ? peekb : (peekb = in.read()); }
public int read() throws IOException { if (peekb >= 0) { int v = peekb; peekb = -1; return v; } else { return in.read(); } }
public int read(byte[] b, int off, int len) throws IOException { if (len == 0) { return 0; } else if (peekb < 0) { return in.read(b, off, len); } else { b[off++] = (byte) peekb; len--; peekb = -1; int n = in.read(b, off, len); return (n >= 0) ? (n + 1) : 1; } }
void readFully(byte[] b, int off, int len) throws IOException { int n = 0; while (n < len) { int count = read(b, off + n, len - n); if (count < 0) { throw new EOFException(); } n += count; } }
public long skip(long n) throws IOException { if (n <= 0) { return 0; } int skipped = 0; if (peekb >= 0) { peekb = -1; skipped++; n--; } return skipped + skip(n); }
public int available() throws IOException { return in.available() + ((peekb >= 0) ? 1 : 0); }
public void close() throws IOException { in.close(); } }
来看一个readint
//ObjectInputStream
public int readInt() throws IOException { return bin.readInt(); }
//BlockDataInputStream
public int readInt() throws IOException { if (!blkmode) { pos = 0; in.readFully(buf, 0, 4); } else if (end - pos < 4) { return din.readInt(); } int v = Bits.getInt(buf, pos); pos += 4; return v; }
附:
//DataOutputStream
public class DataOutputStream extends FilterOutputStream implements DataOutput { /** * The number of bytes written to the data output stream so far. * If this counter overflows, it will be wrapped to Integer.MAX_VALUE. */ protected int written;
/** * bytearr is initialized on demand by writeUTF */ private byte[] bytearr = null;
/** * Creates a new data output stream to write data to the specified * underlying output stream. The counter written is * set to zero. * * @param out the underlying output stream, to be saved for later * use. * @see java.io.FilterOutputStream#out */ public DataOutputStream(OutputStream out) { super(out); } }
public class DataInputStream extends FilterInputStream implements DataInput {
/** * Creates a DataInputStream that uses the specified * underlying InputStream. * * @param in the specified input stream */ public DataInputStream(InputStream in) { super(in); }
/** * working arrays initialized on demand by readUTF */ private byte bytearr[] = new byte[80]; private char chararr[] = new char[80]; }
POJ-1273-Drainage Ditches
http://poj.org/problem?id=1273
基本的最大流,按LRJ的白书写的
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x7fffffff
int ma
开启列模式: Alt+C 鼠标选择 OR Alt+鼠标左键拖动
列模式替换或复制内容(多行):
右键-->格式-->填充所选内容-->选择相应操作
OR
Ctrl+Shift+V(复制多行数据,必须行数一致)
-------------------------------------------------------
About Health Monitor
Beginning with Release 11g, Oracle Database includes a framework called Health Monitor for running diagnostic checks on the database.
About Health Monitor Checks
Health M
实现功能的代码:
# include <stdio.h>
# include <malloc.h>
struct Student
{
int age;
float score;
char name[100];
};
int main(void)
{
int len;
struct Student * pArr;
int i,
http://wiki.sdn.sap.com/wiki/display/BOBJ/Troubleshooting+Crystal+Reports+off+BW#TroubleshootingCrystalReportsoffBW-TracingBOE
Quite useful, especially this part:
SAP BW connectivity
For t