下面列出了java.io.Externalizable#writeExternal ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void externalize(final Externalizable original, final Externalizable copy) throws IOException, ClassNotFoundException {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(baos);
original.writeExternal(out);
out.close();
final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
final ObjectInputStream in = new ObjectInputStream(bais);
copy.readExternal(in);
}
/**
* Writes an object to the ObjectOutput stream.
* If possible, we will send over a magic number instead of the class name
* so that we transfer less amount of data.
* @param inst - an object instance to be serialized, can not be null
* @param out - the ObjectOutput stream we will write the serialized data to
*/
public static void write(Externalizable inst, ObjectOutput out) throws IOException {
boolean is_null=(inst == null);
try {
// if inst is a null value we write this first
out.writeBoolean(is_null);
if(is_null)
return;
//find out if we have a magic number for this class
int magic=mConfigurator.getMagicNumber(inst.getClass());
//-1 means no magic number otherwise we have one
if(magic != -1) {
//true means we use a magic number
out.writeBoolean(true);
//write the magic number
out.writeInt(magic);
}
else {
//we don't have a magic number
out.writeBoolean(false);
//write the classname instead
out.writeUTF(inst.getClass().getName());
}//end if
//write the object data
inst.writeExternal(out);
}
catch(Exception x) {
if(x instanceof IOException)
throw (IOException)x;
else
throw new java.io.IOException(x.toString());
}
}
public static void writeExternalizableList(final List<Externalizable> list, final ObjectOutput out)
throws IOException {
if (list == null) {
out.writeInt(-1);
} else {
final int listSize = list.size();
out.writeInt(listSize);
for (final Externalizable aList : list) {
aList.writeExternal(out);
}
}
}
/**
* Writes an object to the ObjectOutput stream.
* If possible, we will send over a magic number instead of the class name
* so that we transfer less amount of data.
* @param inst - an object instance to be serialized, can not be null
* @param out - the ObjectOutput stream we will write the serialized data to
*/
public static void write(Externalizable inst, ObjectOutput out) throws IOException {
boolean is_null=(inst == null);
try {
// if inst is a null value we write this first
out.writeBoolean(is_null);
if(is_null)
return;
//find out if we have a magic number for this class
int magic=mConfigurator.getMagicNumber(inst.getClass());
//-1 means no magic number otherwise we have one
if(magic != -1) {
//true means we use a magic number
out.writeBoolean(true);
//write the magic number
out.writeInt(magic);
}
else {
//we don't have a magic number
out.writeBoolean(false);
//write the classname instead
out.writeUTF(inst.getClass().getName());
}//end if
//write the object data
inst.writeExternal(out);
}
catch(Exception x) {
if(x instanceof IOException)
throw (IOException)x;
else
throw new java.io.IOException(x.toString());
}
}
@Override
public void write(Kryo kryo, Output output, Externalizable object) {
KryoObjectOutput koo = new KryoObjectOutput(output, kryo);
try {
object.writeExternal(koo);
} catch (IOException e) {
//shouldn't happen
throw new RuntimeException(e);
}
}
public static byte[] toBytes(Externalizable o) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baos);
o.writeExternal(out);
out.flush();
return baos.toByteArray();
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
if (currentClassDesc.forClass().getName().equals("java.lang.String")) {
this.writeUTF((String)obj);
return;
}
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
if (currentClassDesc.forClass().getName().equals("java.lang.String")) {
this.writeUTF((String)obj);
return;
}
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
if (currentClassDesc.forClass().getName().equals("java.lang.String")) {
this.writeUTF((String)obj);
return;
}
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
public void marshal(final Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) {
final Object source = serializationMembers.callWriteReplace(original);
if (source != original && context instanceof ReferencingMarshallingContext) {
((ReferencingMarshallingContext)context).replace(original, source);
}
if (source.getClass() != original.getClass()) {
final String attributeName = mapper.aliasForSystemAttribute("resolves-to");
if (attributeName != null) {
writer.addAttribute(attributeName, mapper.serializedClass(source.getClass()));
}
context.convertAnother(source);
} else {
try {
Externalizable externalizable = (Externalizable)source;
CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() {
public void writeToStream(final Object object) {
if (object == null) {
writer.startNode("null");
writer.endNode();
} else {
ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedClass(object.getClass()), object.getClass());
context.convertAnother(object);
writer.endNode();
}
}
public void writeFieldsToStream(final Map fields) {
throw new UnsupportedOperationException();
}
public void defaultWriteObject() {
throw new UnsupportedOperationException();
}
public void flush() {
writer.flush();
}
public void close() {
throw new UnsupportedOperationException("Objects are not allowed to call ObjectOutput.close() from writeExternal()");
}
};
final CustomObjectOutputStream objectOutput = CustomObjectOutputStream.getInstance(context, callback);
externalizable.writeExternal(objectOutput);
objectOutput.popCallback();
} catch (IOException e) {
throw new StreamException("Cannot serialize " + source.getClass().getName() + " using Externalization", e);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
if (currentClassDesc.forClass().getName().equals("java.lang.String")) {
this.writeUTF((String)obj);
return;
}
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
if (currentClassDesc.forClass().getName().equals("java.lang.String")) {
this.writeUTF((String)obj);
return;
}
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
if (currentClassDesc.forClass().getName().equals("java.lang.String")) {
this.writeUTF((String)obj);
return;
}
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
private void outputObject(final Object obj) throws IOException{
currentObject = obj;
Class currclass = obj.getClass();
/* Get the Class descriptor for this class,
* Throw a NotSerializableException if there is none.
*/
currentClassDesc = ObjectStreamClass.lookup(currclass);
if (currentClassDesc == null) {
// XXX I18N, Logging needed.
throw new NotSerializableException(currclass.getName());
}
/* If the object is externalizable,
* call writeExternal.
* else do Serializable processing.
*/
if (currentClassDesc.isExternalizable()) {
// Write format version
orbStream.write_octet(streamFormatVersion);
Externalizable ext = (Externalizable)obj;
ext.writeExternal(this);
} else {
/* The object's classes should be processed from supertype to subtype
* Push all the clases of the current object onto a stack.
* Remember the stack pointer where this set of classes is being pushed.
*/
int stackMark = classDescStack.size();
try {
ObjectStreamClass next;
while ((next = currentClassDesc.getSuperclass()) != null) {
classDescStack.push(currentClassDesc);
currentClassDesc = next;
}
/*
* For currentClassDesc and all the pushed class descriptors
* If the class is writing its own data
* set blockData = true; call the class writeObject method
* If not
* invoke either the defaultWriteObject method.
*/
do {
WriteObjectState oldState = writeObjectState;
try {
setState(NOT_IN_WRITE_OBJECT);
if (currentClassDesc.hasWriteObject()) {
invokeObjectWriter(currentClassDesc, obj );
} else {
defaultWriteObjectDelegate();
}
} finally {
setState(oldState);
}
} while (classDescStack.size() > stackMark &&
(currentClassDesc = (ObjectStreamClass)classDescStack.pop()) != null);
} finally {
classDescStack.setSize(stackMark);
}
}
}
public static void toStream(@Nonnull final Externalizable obj, @Nonnull final OutputStream out)
throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(out);
obj.writeExternal(oos);
oos.flush();
}
/**
* Writes object to data output. Do not use externalizable interface to avoid marshaller.
*
* @param out Data output.
* @throws IOException If error occurred.
*/
public void writeExternal(ObjectOutput out) throws IOException {
byte[] hdr = new byte[RES_HEADER_SIZE];
U.intToBytes(resType, hdr, 0);
int off = 4;
hdr[off++] = err != null ? (byte)1 : (byte)0;
if (resType == RES_TYPE_BYTE_ARRAY)
U.intToBytes(len, hdr, off);
out.write(hdr);
if (err != null) {
out.writeUTF(err);
out.writeInt(errCode);
if (resType == RES_TYPE_ERR_STREAM_ID)
out.writeLong((Long)res);
return;
}
switch (resType) {
case RES_TYPE_BOOLEAN:
out.writeBoolean((Boolean)res);
break;
case RES_TYPE_LONG:
out.writeLong((Long)res);
break;
case RES_TYPE_BYTE_ARRAY:
byte[][] buf = (byte[][])res;
for (byte[] bytes : buf)
out.write(bytes);
break;
case RES_TYPE_IGFS_PATH:
case RES_TYPE_IGFS_PATH_SUMMARY:
case RES_TYPE_IGFS_FILE:
case RES_TYPE_IGFS_STREAM_DESCRIPTOR:
case RES_TYPE_HANDSHAKE:
case RES_TYPE_MODE_RESOLVER:
case RES_TYPE_STATUS: {
out.writeBoolean(res != null);
if (res != null)
((Externalizable)res).writeExternal(out);
break;
}
case RES_TYPE_COL_IGFS_FILE:
case RES_TYPE_COL_IGFS_PATH:
case RES_TYPE_COL_IGFS_BLOCK_LOCATION: {
Collection<Externalizable> items = (Collection<Externalizable>)res;
if (items != null) {
out.writeInt(items.size());
for (Externalizable item : items)
item.writeExternal(out);
}
else
out.writeInt(-1);
break;
}
}
}
public void writeObject(Object obj) throws IOException {
if (writeObjects) {
if (obj == null) {
write(ObjectStreamConstants.TC_NULL);
} else if (obj instanceof String) {
String s = (String) obj;
long bytesRequired = utfBytesRequired(s);
boolean forceLongHeader = (bytesRequired > Short.MAX_VALUE);
writeUTF(s, bytesRequired, forceLongHeader);
} else if (obj instanceof Externalizable) {
Externalizable e = (Externalizable) obj;
e.writeExternal(this);
} else {
throw new RuntimeException("Object is not Externalizable: " + obj.toString());
}
}
}
/**
* Writes externalizable object.
*
* @param obj Object.
* @throws IOException In case of error.
*/
void writeExternalizable(Object obj) throws IOException {
Externalizable extObj = (Externalizable)obj;
extObj.writeExternal(this);
}