序列化

序列化

計(jì)算機(jī)中最原始的數(shù)據(jù)就是0和1,有電才能驅(qū)動(dòng)計(jì)算機(jī)運(yùn)行,1和0對(duì)應(yīng)電的正負(fù),易經(jīng)有太極生兩儀,兩儀生四象,四象生八卦,八卦衍萬物,所以0和1可衍生萬物,萬物皆對(duì)象,那這對(duì)象怎么保存,最簡(jiǎn)單就是保存0和1就行,對(duì)象轉(zhuǎn)變成0和1就是序列化,0和1轉(zhuǎn)成對(duì)象就是反序列化

存儲(chǔ)數(shù)據(jù)傳輸數(shù)據(jù)

簡(jiǎn)單舉的例子:

存儲(chǔ):在java中的面向?qū)ο缶幊讨校瑪?shù)據(jù)通常是用一個(gè)字段表示,如名字name=張三,字段為name,value為張三,這個(gè)字段在一個(gè)類對(duì)象中,這個(gè)對(duì)象是在程序運(yùn)行中創(chuàng)建在內(nèi)存中的,持久保存"張三"就需要把這個(gè)對(duì)象序列化保存在硬盤上。

傳輸:傳輸和存儲(chǔ)是一樣的,上面說的存儲(chǔ)就是內(nèi)存?zhèn)饔脖P,另一種場(chǎng)景,兩臺(tái)計(jì)算機(jī)之間傳輸數(shù)據(jù),序列化后的數(shù)據(jù)是0和1的2進(jìn)制串,比如兩臺(tái)計(jì)算機(jī)連著一根金屬線,在這跟金屬線上通電與斷電表示1或0,這樣另一臺(tái)計(jì)算機(jī)得到2進(jìn)制串后進(jìn)行反序列化,就可以得到內(nèi)容相同的對(duì)象了。

序列化故名思意就是按序排列變化,"序"就是某種協(xié)議,按這種協(xié)議排列變成另一種形態(tài)

簡(jiǎn)單的概括

  • 序列化: 主要用于網(wǎng)絡(luò)傳輸,數(shù)據(jù)持久化,一般序列化也稱為編碼(Encode)
  • 反序列化: 主要用于從網(wǎng)絡(luò),磁盤上讀取字節(jié)數(shù)組還原成原始對(duì)象,一般反序列化也稱為解碼(Decode)

以上得知序列化是將一個(gè)對(duì)象的數(shù)據(jù)保存或傳輸,怎么樣使這個(gè)對(duì)象能被序列化?

Serializable:可序列化的

Serializable是一個(gè)空接口,中文意思使可序列化的,意思使實(shí)現(xiàn)了這個(gè)接口的javaBean類可以序列化成2進(jìn)制串,使用ObjectOutputStream 序列化,ObjectInputStream 反序列化。

public class SPerson implements Serializable {
//serialVersionUID 是 Java 為每個(gè)序列化類產(chǎn)生的版本標(biāo)識(shí),可用來保證在反序列時(shí),發(fā)送方發(fā)送的和接受方接收的是可兼容的對(duì)象。如果接收方接收的類的 //serialVersionUID 與發(fā)送方發(fā)送的 serialVersionUID 不一致,進(jìn)行反序列時(shí)會(huì)拋出 InvalidClassException
    //
    private static final long serialVersionUID = 2088008379212083287L;
    private String name;
    private int age;
}
public class SerializeableTest {
    public static void main(String[] args){
        SPerson sPerson1 =new SPerson();
        sPerson1.setName("張三");
        sPerson1.setAge(18);
        System.out.println("serializable="+ sPerson1.getName()+"--"+ sPerson1.getAge());
        try {
            ByteArrayOutputStream baos=new ByteArrayOutputStream();
            ObjectOutputStream oos=new ObjectOutputStream(baos);
            oos.writeObject(sPerson1);
            byte[] bs2=  baos.toByteArray();
            System.out.println("serializable序列化后="+ Arrays.toString(bs2));
            ObjectInputStream ojis=new ObjectInputStream(new ByteArrayInputStream(bs2));
            SPerson sPerson2 = (SPerson) ojis.readObject();
            System.out.println("serializable反序列化="+ sPerson2.getName()+"--"+ sPerson2.getAge());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印結(jié)果:

serializable=張三--18
serializable序列化后=[-84, -19, 0, 5, 115, 114, 0, 39, 99, 111, 109, 46, 100, 98, 102, 46, 106, 97, 118, 97, 115, 116, 117, 100, 121, 46, 115, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 46, 83, 80, 101, 114, 115, 111, 110, 28, -6, 24, -114, -30, -7, -80, 87, 2, 0, 2, 73, 0, 3, 97, 103, 101, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 0, 0, 0, 18, 116, 0, 6, -27, -68, -96, -28, -72, -119]
serializable反序列化=張三--18

序列化后的文件直接用sublime打開如下

aced 0005 7372 002e 636f 6d2e 7a65 726f
2e73 6572 6961 6c69 7a61 626c 6564 656d
6f2e 7365 7269 616c 697a 6162 6c65 2e53
7475 6465 6e74 e2d9 8cd7 833d f19e 0200
...
  • AC ED: STREAM_MAGIC. 聲明使用了序列化協(xié)議.
  • 00 05: STREAM_VERSION. 序列化協(xié)議版本.
  • 0x73: TC_OBJECT. 聲明這是一個(gè)新的對(duì)象.
  • 0x72: TC_CLASSDESC. 聲明這里開始一個(gè)新Class。
  • 00 2e: Class名字的長度.

不容易發(fā)現(xiàn)的問題:

  SPerson sPerson1 =new SPerson();
        sPerson1.setName("張三");
        sPerson1.setAge(18);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(sPerson1);
sPerson1.setName("李四");
//oos.writeUnshared(sPerson1);不共享
oos.writeObject(sPerson1);共享
  ObjectInputStream ojis=new ObjectInputStream(new ByteArrayInputStream(bs2));
            SPerson sPerson2 = (SPerson) ojis.readObject();
            SPerson sPerson3 = (SPerson) ojis.readObject();
//以上是想保存一個(gè)李四18,設(shè)置李四后調(diào)用oos.writeObject(sPerson1) 反序列化出來的是兩個(gè)張三,得用oos.writeUnshared(sPerson1);

Parcelable 可打包的

Parcelable是Android為我們提供的序列化的接口,Parcelable相對(duì)于Serializable的使用相對(duì)復(fù)雜一些,但Parcelable的效率相對(duì)Serializable也高很多,Parcelable vs Serializable 號(hào)稱快10倍的效率

Parcelable是Android SDK提供的,它是基于內(nèi)存的,由于內(nèi)存讀寫速度高于硬盤,因此Android中的跨進(jìn)程對(duì)象的傳遞一般使用Parcelable

public class PPerson implements Parcelable {
    private String name;
    private int age;
//反序列化時(shí)構(gòu)建對(duì)象,序列化的數(shù)據(jù)包在Parcel中,Parcel就是包裹的意思
    protected PPerson(Parcel in) {
        name = in.readString();
        age = in.readInt();
    }
//構(gòu)建器,構(gòu)造一個(gè)PPerson對(duì)象和PPerson數(shù)組對(duì)象
    public static final Creator<PPerson> CREATOR = new Creator<PPerson>() {
        @Override
        public PPerson createFromParcel(Parcel in) {
            return new PPerson(in);
        }

        @Override
        public PPerson[] newArray(int size) {
            return new PPerson[size];
        }
    };

//描述包含在這個(gè) Parcelable 實(shí)例的封送表示中的特殊對(duì)象的種類。例如,如果對(duì)象將在 {@link writeToParcel(Parcel, int)} 的輸出中包含文件描述符,則此方法的返回值必須包含 {@link CONTENTS_FILE_DESCRIPTOR} 位。 @return 一個(gè)位掩碼,指示由此 Parcelable 對(duì)象實(shí)例編組的一組特殊對(duì)象類型。
    @Override
    public int describeContents() {
        return 0;
    }
//將數(shù)據(jù)打包到Parcel
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

}

Android也是基于linux,進(jìn)程之間內(nèi)存不共享,因此進(jìn)程之間的信息傳遞需要序列化與反序列化,通常在四大組件之間傳遞對(duì)象需要將對(duì)象序列化,啟動(dòng)一個(gè)Activity交給AMS完成,AMS全名ActivityManagerService,是系統(tǒng)服務(wù),是另一個(gè)進(jìn)程,這里就得序列化了,關(guān)于啟動(dòng)四大組件是比較復(fù)雜的流程,可以看看下面的文章

startActivity啟動(dòng)過程分析:http://gityuan.com/2016/03/12/start-activity/

Android中Intent/Bundle的通信原理及大小限制

速度快,比如兩個(gè)Activity之間傳遞,Activity用于頁面展示,速度一定得快,其次數(shù)據(jù)量也不能過大,大數(shù)據(jù)傳輸,肯定會(huì)導(dǎo)致速度變慢,能感覺頁面明顯切換得慢了,數(shù)據(jù)過大時(shí)會(huì)報(bào)一個(gè)錯(cuò)誤,

Intent 中的 Bundle 是使用 Binder 機(jī)制進(jìn)行數(shù)據(jù)傳送的。能使用的 Binder 的緩沖區(qū)是有大小限制的(有些手機(jī)是 2 M),而一個(gè)進(jìn)程默認(rèn)有 16 個(gè) Binder 線程,所以一個(gè)線程能占用的緩沖區(qū)就更小了( 有人以前做過測(cè)試,大約一個(gè)線程可以占用 128 KB)。所以當(dāng)你看到 The Binder transaction failed because it was too large 這類 TransactionTooLargeException 異常時(shí),你應(yīng)該知道怎么解決了

怎么實(shí)現(xiàn)跨進(jìn)程通信,通過AIDL快速生成代碼,下面是生成的部分代碼

@Override public void addPerson(com.dbf.studyandtest.myaidl.Person person) throws android.os.RemoteException
{
    //先獲得傳入和傳出的打包對(duì)象Parcel,看到obtain應(yīng)該是用了享元模式,與handler傳消息的message一樣,對(duì)象頻繁使用,減少new,重復(fù)利用已經(jīng)new好的對(duì)象
  android.os.Parcel _data = android.os.Parcel.obtain();//傳入數(shù)據(jù),就是給另一個(gè)進(jìn)程的數(shù)據(jù)
  android.os.Parcel _reply = android.os.Parcel.obtain();//傳出數(shù)據(jù),就是另一個(gè)進(jìn)程回傳的數(shù)據(jù)
  try {
    _data.writeInterfaceToken(DESCRIPTOR);
    if ((person!=null)) {
      _data.writeInt(1);
      person.writeToParcel(_data, 0);//將數(shù)據(jù)寫入Parcel,可以看到我們實(shí)現(xiàn)Parcelable的類,調(diào)用的是native方法
    }
    else {
      _data.writeInt(0);
    }
    boolean _status = mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
    if (!_status && getDefaultImpl() != null) {
      getDefaultImpl().addPerson(person);
      return;
    }
    _reply.readException();
    if ((0!=_reply.readInt())) {
      person.readFromParcel(_reply);//從Parcel讀出數(shù)據(jù),可以看到我們實(shí)現(xiàn)Parcelable的類,也是調(diào)用native方法
    }
  }
  finally {
      //最后釋放
    _reply.recycle();
    _data.recycle();
  }
}

linux中分用戶空間和內(nèi)核空間,先從用戶空間其中一個(gè)進(jìn)程cp到內(nèi)核空間,再從內(nèi)核空間映射到用戶空間的另一個(gè)進(jìn)程,想要達(dá)到這個(gè)目的要繼承Binder實(shí)現(xiàn)IInterface,代碼形式都是固定的,所以有了AIDL,Android Interface Definition Language,即Android接口定義語言

Parcelable與Serializable的性能比較

Serializable性能分析

Serializable是Java中的序列化接口,其使用起來簡(jiǎn)單但開銷較大(因?yàn)镾erializable在序列化過程中使用了反射機(jī)制,故而會(huì)產(chǎn)生大量的臨時(shí)變量,從而導(dǎo)致頻繁的GC),并且在讀寫數(shù)據(jù)過程中,它是通過IO流的形式將數(shù)據(jù)寫入到硬盤或者傳輸?shù)骄W(wǎng)絡(luò)上。

Parcelable性能分析

Parcelable則是以IBinder作為信息載體,在內(nèi)存上開銷比較小,因此在內(nèi)存之間進(jìn)行數(shù)據(jù)傳遞時(shí),推薦使用Parcelable,而Parcelable對(duì)數(shù)據(jù)進(jìn)行持久化或者網(wǎng)絡(luò)傳輸時(shí)操作復(fù)雜,一般這個(gè)時(shí)候推薦使用Serializable。

性能比較總結(jié)描述

首先Parcelable的性能要強(qiáng)于Serializable的原因我需要簡(jiǎn)單的闡述一下

  • 在內(nèi)存的使用中,前者在性能方面要強(qiáng)于后者
  • 后者在序列化操作的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量,(原因是使用了反射機(jī)制)從而導(dǎo)致GC的頻繁調(diào)用,因此在性能上會(huì)稍微遜色
  • Parcelable是以Ibinder作為信息載體的.在內(nèi)存上的開銷比較小,因此在內(nèi)存之間進(jìn)行數(shù)據(jù)傳遞的時(shí)候,Android推薦使用Parcelable,既然是內(nèi)存方面比價(jià)有優(yōu)勢(shì),那么自然就要優(yōu)先選擇.
  • 在讀寫數(shù)據(jù)的時(shí)候,Parcelable是在內(nèi)存中直接進(jìn)行讀寫,而Serializable是通過使用IO流的形式將數(shù)據(jù)讀寫入在硬盤上.
    但是:雖然Parcelable的性能要強(qiáng)于Serializable,但是仍然有特殊的情況需要使用Serializable,而不去使用Parcelable,因?yàn)镻arcelable無法將數(shù)據(jù)進(jìn)行持久化,因此在將數(shù)據(jù)保存在磁盤的時(shí)候,仍然需要使用后者,因?yàn)榍罢邿o法很好的將數(shù)據(jù)進(jìn)行持久化.(原因是在不同的Android版本當(dāng)中,Parcelable可能會(huì)不同,因此數(shù)據(jù)的持久化方面仍然是使用Serializable)

Protobuf

  • 序列化數(shù)據(jù)非常簡(jiǎn)潔,緊湊,與 XML 相比,其序列化之后的數(shù)據(jù)量約為 1/3 到 1/10。
  • 解析速度非???,比對(duì)應(yīng)的 XML 快約 20-100 倍。

一、配置protobuf

插件github地址:https://github.com/google/protobuf-gradle-plugin

1.在項(xiàng)目根目錄的build.gradle中配置:

dependencies {
    classpath 'com.android.tools.build:gradle:4.1.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.17'//protobuf插件
}

2.在模塊中的build.gradle中配置:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.protobuf'//protobuf插件
android {
    ...
         sourceSets {
        main {
             java {
            srcDir 'src/main/java'
            }
            proto {
                srcDir 'src/main/proto'//添加protobuf目錄,在里面編寫需要序列化的文件
            }
        }
         }
}

protobuf {
    //配置protoc編譯器
    protoc {
        artifact = 'com.google.protobuf:protoc:3.8.0'//這里的版本跟斜面依賴的版本一致
    }
    //這里配置生成目錄,編譯后會(huì)在build的目錄下生成對(duì)應(yīng)的java文件
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                remove java
            }
            task.builtins {
                java {}
            }
        }
    }
}
dependencies {
    implementation 'com.google.protobuf:protobuf-java:3.8.0'
}

3.Settings Plugins 搜索安裝 Protobuf Support 插件,裝好后可以識(shí)別出.proto文件

二、編寫protobuf

.proto文件編寫 github地址:https://github.com/protocolbuffers/protobuf

proto3本版本java:https://developers.google.com/protocol-buffers/docs/proto3

例子:

syntax = "proto3";//版本 之前有proto2
//package tutorial;
/**java_multiple_files = true
選項(xiàng)可以生成單獨(dú)的.java每個(gè)生成的類的文件
(而不是.java為包裝類生成單個(gè)文件的遺留行為,使用包裝類作為外部類,并將所有其他類嵌套在包裝類中)。
 */
option java_multiple_files = true;
/** java_package指定生成的類應(yīng)該使用的 Java 包名稱。
如果您沒有明確指定,它只是匹配package聲明給出的包名,
但這些名稱通常不是合適的 Java 包名(因?yàn)樗鼈兺ǔ2灰杂蛎_頭)。
 */
option java_package = "com.dbf.studyandtest.proto";
/**java_outer_classname選項(xiàng)定義將表示此文件的包裝類的類名。
如果你不java_outer_classname明確給出a ,它會(huì)通過將文件名轉(zhuǎn)換為大寫駝峰來生成。
例如,默認(rèn)情況下,“my_proto.proto”將使用“MyProto”作為包裝類名稱。
 */
option java_outer_classname = "_Person";
message Person{
  /**每個(gè)元素上的“= 1”、“= 2”標(biāo)記標(biāo)識(shí)字段在二進(jìn)制編碼中使用的唯一“標(biāo)簽”。
  標(biāo)記數(shù)字 1-15 需要比更高數(shù)字少一個(gè)字節(jié)來編碼,因此作為一種優(yōu)化,您可以決定將這些標(biāo)記用于常用或重復(fù)的元素,
  而將標(biāo)記 16 和更高的標(biāo)記用于不太常用的可選元素。重復(fù)字段中的每個(gè)元素都需要重新編碼標(biāo)簽編號(hào),因此重復(fù)字段特別適合這種優(yōu)化。
   */
  //指定字段的類型 定義字段的編號(hào),在Protocol Buffers中,字段的編號(hào)非常重要,字段名僅僅是作為參考和生成代碼用。需要注意的是字段的編號(hào)區(qū)間范圍,其中19000 ~ 19999被Protocol Buffers作為保留字段
  string name = 1;
  int32  age  = 2;

//  message Home{
//    string address = 1;
//  }
//  Home   home = 3;
}

//message Family {
//  Person person = 1;
//}

Make project 一下自動(dòng)生成代碼

/**
 * Protobuf type {@code Person}
 */
public  final class Person extends com.google.protobuf.GeneratedMessageV3 implements PersonOrBuilder {
//省略600多行代碼
}

Serializable對(duì)比

public static void main(String[] args) throws  Exception{
    Person person = Person.newBuilder().setName("張三").setAge(18).build();
    System.out.println("protobuf="+person.getName()+"--"+person.getAge());
    //序列化
    byte[] bs=person.toByteArray();
    System.out.println("protobuf序列化后="+Arrays.toString(bs));
    Person person2=Person.parseFrom(bs);
    System.out.println("protobuf反序列化="+person2.getName()+"--"+person2.getAge());
    System.out.println("\n----------------分割線-------------\n");
    SPerson sPerson1 =new SPerson();
    sPerson1.setName("張三");
    sPerson1.setAge(18);
    System.out.println("serializable="+ sPerson1.getName()+"--"+ sPerson1.getAge());
    try {
        ByteArrayOutputStream baos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(baos);
        oos.writeObject(sPerson1);
        byte[] bs2=  baos.toByteArray();
        System.out.println("serializable序列化后="+Arrays.toString(bs2));
        ObjectInputStream ojis=new ObjectInputStream(new ByteArrayInputStream(bs2));
        SPerson sPerson2 = (SPerson) ojis.readObject();
        System.out.println("serializable反序列化="+ sPerson2.getName()+"--"+ sPerson2.getAge());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

打印結(jié)果:

protobuf=張三--18
protobuf序列化后=[10, 6, -27, -68, -96, -28, -72, -119, 16, 18]
protobuf反序列化=張三--18

----------------分割線-------------

serializable=張三--18
serializable序列化后=[-84, -19, 0, 5, 115, 114, 0, 39, 99, 111, 109, 46, 100, 98, 102, 46, 106, 97, 118, 97, 115, 116, 117, 100, 121, 46, 115, 101, 114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 46, 83, 80, 101, 114, 115, 111, 110, 28, -6, 24, -114, -30, -7, -80, 87, 2, 0, 2, 73, 0, 3, 97, 103, 101, 76, 0, 4, 110, 97, 109, 101, 116, 0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 120, 112, 0, 0, 0, 18, 116, 0, 6, -27, -68, -96, -28, -72, -119]
serializable反序列化=張三--18

.proto Type Notes C++ Type Java/Kotlin Type[1] Python Type[3] Go Type Ruby Type C# Type PHP Type Dart Type
double double double float float64 Float double float double
float float float float float32 Float float float double
int32 使用可變長度編碼。 編碼負(fù)數(shù)效率低下 - 如果您的字段可能具有負(fù)值,請(qǐng)改用 sint32。 int32 int int int32 Fixnum or Bignum (as required) int integer int
int64 使用可變長度編碼。 編碼負(fù)數(shù)效率低下 - 如果您的字段可能具有負(fù)值,請(qǐng)改用 sint64。 int64 long int/long[4] int64 Bignum long integer/string[6] Int64
uint32 使用可變長度編碼。 uint32 int[2] int/long[4] uint32 Fixnum or Bignum (as required) uint integer int
uint64 使用可變長度編碼。 uint64 long[2] int/long[4] uint64 Bignum ulong integer/string[6] Int64
sint32 使用可變長度編碼。 有符號(hào)整數(shù)值。 這些比常規(guī) int32 更有效地編碼負(fù)數(shù)。 int32 int int int32 Fixnum or Bignum (as required) int integer int
sint64 使用可變長度編碼。 有符號(hào)整數(shù)值。 這些比常規(guī) int64 更有效地編碼負(fù)數(shù)。 int64 long int/long[4] int64 Bignum long integer/string[6] Int64
fixed32 總是四個(gè)字節(jié)。 如果值通常大于 228,則比 uint32 更有效。 uint32 int[2] int/long[4] uint32 Fixnum or Bignum (as required) uint integer int
fixed64 總是八個(gè)字節(jié)。 如果值通常大于 256,則比 uint64 更有效。 uint64 long[2] int/long[4] uint64 Bignum ulong integer/string[6] Int64
sfixed32 總是四個(gè)字節(jié)。 int32 int int int32 Fixnum or Bignum (as required) int integer int
sfixed64 總是八個(gè)字節(jié)。 int64 long int/long[4] int64 Bignum long integer/string[6] Int64
bool bool boolean bool bool TrueClass/FalseClass bool boolean bool
string 字符串必須始終包含 UTF-8 編碼或 7 位 ASCII 文本,并且長度不能超過 232。 string String str/unicode[5] string String (UTF-8) string string String
bytes 可以包含不超過 232 的任意字節(jié)序列。 string ByteString str (Python 2) bytes (Python 3) []byte String (ASCII-8BIT) ByteString string
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天我們來一起聊一下序列化和反序列化,其實(shí)這兩個(gè)“活寶”對(duì)大家來說都不陌生,而且也會(huì)覺得這有什么好聊的,其實(shí)筆者之...
    初夏的雪閱讀 1,091評(píng)論 0 1
  • 序列化 將數(shù)據(jù)結(jié)構(gòu)或?qū)ο筠D(zhuǎn)換成二進(jìn)制串的過程。 反序列化 將在序列化過程中所生成的二進(jìn)制串轉(zhuǎn)換成數(shù)據(jù)結(jié)構(gòu)或者對(duì)象的...
    壹元伍角叁分閱讀 401評(píng)論 1 1
  • 序列化 定義以及相關(guān)概念 由于在系統(tǒng)底層,數(shù)據(jù)的傳輸形式是簡(jiǎn)單的字節(jié)序列形式傳遞,即在底層,系統(tǒng)不認(rèn)識(shí)對(duì)象,只認(rèn)識(shí)...
    WaterYuan閱讀 264評(píng)論 0 0
  • 序列化定義以及相關(guān)概念 定義:將數(shù)據(jù)結(jié)構(gòu)或?qū)ο筠D(zhuǎn)換成二進(jìn)制串的過程。 由于在系統(tǒng)底層,數(shù)據(jù)的傳輸形式是簡(jiǎn)單的字節(jié)序...
    積跬步以致千里_ylc閱讀 805評(píng)論 0 0
  • 今天青石的票圈出鏡率最高的,莫過于張藝謀的新片終于定檔了。 一張滿溢著水墨風(fēng)的海報(bào)一次次的出現(xiàn)在票圈里,也就是老謀...
    青石電影閱讀 10,890評(píng)論 1 2

友情鏈接更多精彩內(nèi)容