`
goodscript
  • 浏览: 73035 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

自定义序列化 减少序列化对象的大小

 
阅读更多
定义一个实现序列化接口的bean 并重写readObject和writeObject方法
实现类中所有的字段都使用transient 修饰、表示在序列化的时候不保存该字段
package mytest;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TestBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private transient Long code;
	private transient String text;

	private transient Date d;

	private transient List<String> list;

	private transient List<String> list2;

	public Long getCode() {
		return code;
	}

	public void setCode(Long code) {
		this.code = code;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public Date getD() {
		return d;
	}

	public void setD(Date d) {
		this.d = d;
	}

	public List<String> getList() {
		return list;
	}

	public void setList(List<String> list) {
		this.list = list;
	}

	public List<String> getList2() {
		return list2;
	}

	public void setList2(List<String> list2) {
		this.list2 = list2;
	}

	/**
	 * 序列化对象的方法的writeObject
	 * @param os
	 * @throws IOException
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	private void writeObject(ObjectOutputStream os) throws IOException, IllegalArgumentException,
			IllegalAccessException {
		os.defaultWriteObject();//java对象序列化默认操作
		Field[] fs = this.getClass().getDeclaredFields();
		for (Field field : fs) {
			String f = field.getName();
			if ("serialVersionUID".equals(f))
				continue;
			int mod = field.getModifiers();
			if (Modifier.isTransient(mod))
				setObjectOutputStream(os, field);

		}
	}

	/**
	 * 反序列化对象的方法readObject
	 * @param is
	 * @throws IOException
	 * @throws ClassNotFoundException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException, IllegalArgumentException,
			IllegalAccessException {
		is.defaultReadObject();//java对象反序列化默认操作
		Field[] fs = this.getClass().getDeclaredFields();
		for (Field field : fs) {
			String f = field.getName();
			if ("serialVersionUID".equals(f))
				continue;
			int mod = field.getModifiers();
			if (Modifier.isTransient(mod))
				readObjectInputStream(is, field);
		}
	}

	@SuppressWarnings("unchecked")
	private void setObjectOutputStream(ObjectOutputStream os, Field field) throws IOException,
			IllegalArgumentException, IllegalAccessException {
		Class<?> type = field.getType();

		Object v = field.get(this);
		if (type == String.class || type == Long.class || type == Integer.class) {
			os.writeObject(v);
		} else if (type == java.util.Date.class || type == java.sql.Date.class) {
			os.writeObject(v);
		} else if (type == int.class) {
			os.writeInt(Integer.parseInt(v.toString()));
		} else if (type == long.class) {
			os.writeLong(Long.parseLong(v.toString()));
		} else if (type == List.class) {
			List<String> l = (List<String>) v;
			os.writeInt(l.size());
			for (String s : l) {
				os.writeObject(s);
			}
		}
	}

	private void readObjectInputStream(ObjectInputStream is, Field f) throws IllegalArgumentException,
			IllegalAccessException, IOException, ClassNotFoundException {
		Class<?> type = f.getType();
		if (type == String.class || type == Long.class || type == Integer.class) {
			f.set(this, is.readObject());
		} else if (type == java.util.Date.class || type == java.sql.Date.class) {
			f.set(this, is.readObject());
		} else if (type == int.class) {
			f.set(this, is.readInt());
		} else if (type == long.class) {
			f.set(this, is.readLong());
		} else if (type == List.class) {
			int size = is.readInt();
			List<String> setList = new ArrayList<String>();
			for (int i = 0; i < size; i++) {
				Object data = is.readObject();
				setList.add(data.toString());
			}
			f.set(this, setList);
		}
	}

}


测试类
package mytest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;

public class SerializeTest {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		TestBean tb = new TestBean();
//		tb.setCode(null);
		tb.setText("中文");
		tb.setD(new Date());
		List<String> list = new ArrayList<String>();
		list.add("1");
		list.add("2");
		list.add("3");
		list.add("4");
		tb.setList(list);
		List<String> list2 = new ArrayList<String>();
		list2.add("1");
		list2.add("2");
		list2.add("3");
		list2.add("4");
		list2.add("5");
		tb.setList2(list2);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream out = new ObjectOutputStream(bos);
		out.writeObject(tb);
		out.flush();
		out.close();
		System.out.println(new String(bos.toByteArray()));
		System.out.println(bos.size());
		ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
		TestBean tb2 = (TestBean) in.readObject();
		System.out.println(tb2.getD());
	}
}

经过测试一个序列化对象的大小有:170字节
经过处理后大小变成:92字节
代码写得比较丑、以后再慢慢优化
只是为了保存一下
分享到:
评论

相关推荐

    自定义序列化对象c#.docx

    为了减少序列化后的字符串大小,它还移除了多余的分隔符。 2. **自定义反序列化函数** `DeserializeObject&lt;T&gt;`: 这个泛型函数接收一个字符串`s`,根据字符串反序列化回指定类型`T`的对象。它首先获取目标类型的...

    dotnet-Unity最快的序列化反序列化工具

    3. **自定义类型支持**:Unity的内置序列化系统可能对某些自定义类型处理不佳,而DreamSerialize可能允许开发者自定义序列化逻辑,确保所有数据类型都能正确地被序列化和反序列化。 4. **轻量级**:为了适应游戏...

    序列化和反序列化

    6. **自定义序列化行为** 开发者可以通过实现特定接口(如`.NET`中的`ISerializable`)或使用特性(如`[Serializable]`、`[XmlElement]`等)来自定义序列化和反序列化的行为。这可以用来排除某些字段、指定序列化...

    关于Java对象序列化您不知道的5件事Java开发Java

    序列化对象时需要注意安全问题,因为恶意用户可以构造特殊的序列化数据来执行任意代码。为了避免这种情况,应当避免对不可信的数据进行反序列化,并且限制哪些类可以被序列化。 8. **ObjectStreamClass**: `java...

    加快Java的文件序列化速度

    - 对于经常访问的数据,可以考虑使用缓存机制,如Redis或本地缓存,减少序列化和反序列化的次数。 12. **预分配文件大小**: - 在序列化前预分配文件大小,可以减少磁盘碎片,提高写入速度。 13. **使用池化技术...

    java序列化和反序列化1

    - `java.io.ObjectOutputStream`:对象输出流,提供了`writeObject(Object obj)`方法用于序列化对象,将对象转换为字节流并写入到输出流(如文件输出流)。 - `java.io.ObjectInputStream`:对象输入流,提供了`...

    Hessian 的字段序列化小记

    这对于我们自定义序列化逻辑或优化现有应用的性能都非常有价值。 5. **应用场景** - 在分布式服务间通信中,Hessian常用于构建轻量级的RPC(远程过程调用)框架,提供高效的二进制序列化能力。 - 在存储场景下,...

    Boost序列化

    - **可扩展性**:可以通过自定义序列化器来支持自定义类型。 - **高效性**:通过模板元编程技术优化序列化过程,减少运行时开销。 #### 序列化模式 Boost序列化支持两种主要模式:侵入式(Intrusive)和非侵入式...

    jackson 使用方法(序列化效率很高)

    3. **类型安全的反序列化**:Jackson提供了类型令牌(`TypeReference`)或自定义类型解析器(`JsonDeserializer`),以确保反序列化时保持类型安全,尤其是在处理复杂数据结构时。 4. **流式API**:除了基于树模型...

    WeifenLuo 序列化改进

    8. **用户自定义配置**:允许用户保存特定的布局设置,比如自定义的窗口大小和位置,可以通过改进序列化机制来实现。 文件名为`GenericDockPanelSuite`可能表示这是一个通用的DockPanel Suite实现,可能包含了对...

    Netty之序列化协议

    在Netty中实现序列化,通常需要自定义`MessageToByteEncoder`和`MessageToMessageDecoder`,这两个类负责编码和解码数据。编码器将应用程序对象转化为字节数组,解码器则反之。例如,使用protobuf时,可以创建...

    结构体序列化读写二进制文件类

    序列化(Serialization)是将数据对象转换为可以存储或传输的格式的过程。在本例中,它涉及将结构体实例转换为二进制流,以便保存到文件。这样做的好处在于,二进制格式通常占用更少的存储空间,并且可以更快地读取...

    cpp-针对R的数据帧闪电快速序列化

    序列化是指将数据结构或对象转换为字节流的过程,以便可以存储在磁盘上或在网络中传输。反序列化则是将字节流恢复为原始数据结构或对象的过程。在R中,`saveRDS()` 和 `readRDS()` 函数是常用的序列化工具,但它们...

    cpp-cmpMessagePack序列化的实现协议

    3. **性能优化**:cpp-cmp设计时考虑了性能,尽可能减少不必要的内存分配和拷贝,以提高序列化和反序列化速度。 4. **错误处理**:在处理过程中,cpp-cmp会检查数据的有效性和一致性,如果出现错误,它会抛出异常,...

    详解PHP序列化反序列化的方法

    // 自定义序列化函数 function my_serialize($obj_array) { return base64_encode(gzcompress(serialize($obj_array))); } // 自定义反序列化函数 function my_unserialize($str) { return unserialize...

    JSON.NET10.0.3最新版

    9. **减少序列化后的JSON大小**:JSON.NET提供了各种选项来压缩JSON输出,例如忽略空值、去除默认值、使用引用等,以减小网络传输的数据量。 10. **可扩展性**:JSON.NET的源代码开放,允许开发者根据需要进行定制...

    .NET中的优化序列化

    2. **减少序列化开销**:仅序列化必要的字段,避免对大型对象或复杂数据结构的序列化。 3. **利用缓存**:对经常使用的对象进行缓存,避免重复的序列化和反序列化操作。 4. **并行处理**:如果可能,利用多线程或...

    fastJson属性配置说明

    26. **NotWriteDefaultValue**:不输出默认值,减少序列化后的文本大小。 27. **BrowserSecure**:确保 JSON 输出安全,避免 XSS 攻击。 28. **IgnoreNonFieldGetter**:忽略非字段 getter 方法。 29. **...

    spark代码相关的实例

    综上所述,本实例主要涵盖了Spark中的Kryo序列化库的使用,包括启用Kryo、注册自定义类、优化配置以及自定义序列化策略。通过深入理解和应用这些知识,开发者可以提高Spark应用程序的执行效率和内存管理能力。

Global site tag (gtag.js) - Google Analytics