简体   繁体   English

如何提高序列化类的输出效率?

[英]how to make output of serialized class more efficient?

I am serializing a class (save the contents of the class) so that i can restore it at a later time. 我正在序列化一个类(保存该类的内容),以便以后可以恢复它。 so i implemented built-in serialization mechanism using ObjectOutputStream class, but the output size is quite large. 所以我使用ObjectOutputStream类实现了内置的序列化机制,但是输出量很大。

but i want to make the output more efficient, or smaller in size, than that generated by the built-in serialization method. 但我想使输出比内置序列化方法生成的输出更有效或更小。 How can i make the output more efficient ? 如何提高输出效率?

I know that, 我知道,

Java supports serialization, which is the capability of taking an object and creating a byte representation that can be used to restore the object at a later time. Java支持序列化,这是获取对象并创建字节表示形式的功能,该功能可在以后用于恢复对象。 By using an internal serialization mechanism, most of the setup to serialize objects is taken care of. 通过使用内部序列化机制,可以完成大多数用于序列化对象的设置。 Java will transform the properties of an object into a byte stream, which can then be saved to a file or transmitted over the wire. Java将对象的属性转换为字节流,然后可以将其保存到文件或通过有线传输。

but I am already doing that, and i need more efficient way. 但我已经在这样做了,我需要更有效的方法。 is it even possible ? 可能吗?

I'd recommend against Java built-in serialization. 我建议不要使用Java内置序列化。 You'd better go with a serialization library, like Jackson , or any other you like. 您最好使用序列化库,例如Jackson或您喜欢的任何其他库。

Now, with regard to the output size, you could compress the output by decorating the ObjectOutputStream with Java's GZIPOutputStream : 现在,关于输出大小,您可以通过用Java的GZIPOutputStream装饰ObjectOutputStream来压缩输出:

OutputStream os = ...; // this is your ObjectOutputStream
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(os);

and then work with gzipOutputStream instance as if it were your original ObjectOutputStream . 然后使用gzipOutputStream实例,就好像它是原始的ObjectOutputStream

Keep in mind that you should also use Java's GZIPInputStream in order to read the serialized data: 请记住,还应该使用Java的GZIPInputStream来读取序列化的数据:

InputStream is = ...; // this is your actual InputStream
GZIPInputStream gzipInputStream = new GZIPInputStream(is);

and then work with gzipInputStream instance as if it were your original InputStream . 然后使用gzipInputStream实例,就像它是您的原始InputStream

If there are things in the class you don't require to save to file use the java keyword: transient and it won't be serialized. 如果类中有某些内容,您不需要保存到文件中,请使用java关键字:transient,它将不会被序列化。

eg private transient Logger logger = Logger.getLogger(); 例如, private transient Logger logger = Logger.getLogger();

Why don't you try compressing the output file.. I found this article : http://www.devsumo.com/technotes/2014/03/java-compressed-serialization/ 您为什么不尝试压缩输出文件。我发现了这篇文章: http : //www.devsum​​o.com/technotes/2014/03/java-compressed-serialization/

GZIPOutputStream is used to compress the output. GZIPOutputStream用于压缩输出。

You can use a custom format to serialize your class. 您可以使用自定义格式来序列化您的类。 In this case I'd use a binary format to reduce the final size, avoiding textual representations such as XML and JSON. 在这种情况下,我将使用二进制格式来减小最终大小,避免使用XML和JSON等文本表示形式。

An example implementation could be something like the following: 一个示例实现可能如下所示:

public class YourClass
{
  private int field1;
  private byte field2;
  // ...

  public void encode(DataOutput stream) throws IOException
  {
     stream.writeInt(field1);
     stream.writeByte(field2);
  }

  public static YourClass decode(DataInput stream) throws IOException
  {
    YourClass ret = new YourClass();
    ret.field1 = stream.readInt();
    ret.field2 = stream.readByte();
    return ret;
  }
}

The encode method is used to write the class to a stream, the decode method reads it back from it. encode方法用于将类写入流, decode方法从该类读取流。 The decode method is static so that it can also create the class instance without relying on the user to do it manually. decode方法是静态的,因此它也可以创建类实例,而无需依赖用户手动进行操作。

Also note that if your class has class instances as member fields and you want to preserve them you have to encode these too, so it's better if you include the encode and decode methods in all classes that are serializable or are part of a serializable class. 还要注意,如果您的类具有作为成员字段的类实例,并且您也想对其进行编码,那么最好在所有可序列化或可序列化类的类中都包含encodedecode方法。

Of course this means quite a lot of work, as all fields have to be read and written by hand, but is probably the most space efficient solution. 当然,这意味着要进行大量工作,因为所有领域都必须手工读写,但这可能是最节省空间的解决方案。

You can use JSONReader and JsonWriter and convert the object into JSON format and you can store it somewhere for future use. 您可以使用JSONReaderJsonWriter并将对象转换为JSON格式,并且可以将其存储在某个地方以备将来使用。 In this case your class not needs to implement serializable interface. 在这种情况下,您的类无需实现可序列化的接口。 and for storing the json in database requires very less space. 并且用于将json存储在数据库中所需的空间非常少。 and it become lightweight 变得轻巧

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM