Java 如何使序列化类的输出更有效?

Java 如何使序列化类的输出更有效?,java,serialization,Java,Serialization,我正在序列化一个类(保存该类的内容),以便以后可以还原它。 因此,我使用ObjectOutputStream类实现了内置的序列化机制,但输出大小相当大 但是我想使输出比内置序列化方法生成的输出更高效,或者更小。如何使输出更有效率 我知道, Java支持序列化,这是一种获取 对象并创建可用于还原的字节表示形式 该对象将在稍后的时间被删除。通过使用内部序列化 机制中,序列化对象的大部分设置都已完成。 Java将对象的属性转换为字节流, 然后可以将其保存到文件或通过网络传输 但我已经在这样做了,我需要

我正在序列化一个类(保存该类的内容),以便以后可以还原它。 因此,我使用
ObjectOutputStream
类实现了内置的序列化机制,但输出大小相当大

但是我想使输出比内置序列化方法生成的输出更高效,或者更小。如何使输出更有效率

我知道,

Java支持序列化,这是一种获取 对象并创建可用于还原的字节表示形式 该对象将在稍后的时间被删除。通过使用内部序列化 机制中,序列化对象的大部分设置都已完成。 Java将对象的属性转换为字节流, 然后可以将其保存到文件或通过网络传输


但我已经在这样做了,我需要更有效的方法。甚至可能吗?

如果类中存在不需要保存到文件的内容,请使用java关键字:transient,它将不会被序列化


e、 g
private transient Logger=Logger.getLogger()

如果类中存在不需要保存到文件的内容,请使用java关键字:transient,它不会被序列化


e、 g
private transient Logger=Logger.getLogger()

为什么不尝试压缩输出文件。。 我发现这篇文章:


GZIPOutputStream用于压缩输出

为什么不尝试压缩输出文件。。 我发现这篇文章:


GZIPOutputStream用于压缩输出

可以使用自定义格式序列化类。在本例中,我将使用二进制格式来减少最终大小,避免XML和JSON等文本表示

示例实现可能类似于以下内容:

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;
  }
}
encode
方法用于将类写入流,而
decode
方法从流中读回类。
decode
方法是静态的,因此它也可以创建类实例,而无需依赖用户手动执行

还请注意,如果您的类具有类实例作为成员字段,并且您希望保留它们,那么您也必须对它们进行编码,因此最好在所有可序列化或属于可序列化类的类中包含
encode
decode
方法


当然,这意味着要做很多工作,因为所有字段都必须手工读写,但这可能是最节省空间的解决方案。

您可以使用自定义格式来序列化类。在本例中,我将使用二进制格式来减少最终大小,避免XML和JSON等文本表示

示例实现可能类似于以下内容:

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;
  }
}
encode
方法用于将类写入流,而
decode
方法从流中读回类。
decode
方法是静态的,因此它也可以创建类实例,而无需依赖用户手动执行

还请注意,如果您的类具有类实例作为成员字段,并且您希望保留它们,那么您也必须对它们进行编码,因此最好在所有可序列化或属于可序列化类的类中包含
encode
decode
方法


当然,这意味着要做很多工作,因为所有字段都必须手工读写,但这可能是最节省空间的解决方案。

我建议不要使用Java内置序列化。您最好使用序列化库,例如,或您喜欢的任何其他库

现在,关于输出大小,您可以通过使用Java的

然后使用
gzipOutputStream
实例,就像它是原始的
ObjectOutputStream
一样

请记住,您还应该使用Java来读取序列化数据:

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

然后使用
gzipInputStream
实例,就像它是您的原始
InputStream

一样,我建议不要使用Java内置序列化。您最好使用序列化库,例如,或您喜欢的任何其他库

现在,关于输出大小,您可以通过使用Java的

然后使用
gzipOutputStream
实例,就像它是原始的
ObjectOutputStream
一样

请记住,您还应该使用Java来读取序列化数据:

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

然后使用
gzip输入流
实例,就像它是原始的
InputStream

一样。您可以使用并将对象转换为JSON格式,并将其存储在某处以备将来使用。在这种情况下,您的类不需要实现可序列化接口。而且在数据库中存储json所需的空间非常少。它变得轻量级

您可以使用并将对象转换为JSON格式,您可以将其存储在某处供将来使用。在这种情况下,您的类不需要实现可序列化接口。而且在数据库中存储json所需的空间非常少。而且它变得轻量级

使用其他使用不同编码的框架,如kryo、protobuf等。您能否实现
Externalizable
接口?使用其他使用不同编码的框架,如kryo、protobuf等。您能否实现
Externalizable
接口?