编码和序列化 - Go语言中文社区

编码和序列化



我认为一个是用于传输,一个是用于存储。用于传输,把一块数据变成bytes,存储,主要是针对文本,一个文本对应几个bytes。??

我认为,编码解码只是字节序的翻译机制,是针对人类视觉的,是人类语言和计算机语言交流用的,设计到显示的,显示成人类语言的,都需要编码解码,所谓的码指的是bytes。而序列化是数据块编程字节序的方式,是数据传输或者存储时候用的,序列化是计算机和计算机交流时候用的,他们之间的语言。

归根结底,是人类和计算机的交流翻译还是计算机之间的交流数据格式~如果你感觉编码头大,可以用机器码输入计算机,让计算机去识别你输入的机器码,不涉及到给人显示的,不需要考虑编码解码,你看到的乱码,计算机表示很无辜,只是你用了一个错误的翻译辞典,涉及到显示的,人类要想看懂bytes,需要知道机器码是用那种格式编码的,然后再用这种格式解码bytes,人类就能看懂显示了。而序列化,就是机器和机器之间数据交流的翻译,都变成字节序,都接收字节序,机器们之间就能看懂了。

序列化的本质,

我记得计算机内存的地址单位是字节,对象是一个字节序,这个字节序里还有引用地址,如何把一块内存对象,转化成可以存储的数据块,地址的部分的保存,磁盘或者网络传输时候,是没法识别的,就需要序列化,还有可能不同语言,表示一个数据,使用的字节数不同,把java语言的对象,序列化成字节序,再传输给c++语言的进程,拿到这个字节序,再翻译成内存中的数据块-即c++对象。

凡是离开内存需要传输或者持久化的数据,都要先进行序列化。数据离开内存,进行io的时候,就应该学习序列化的概念了。序列化就是流化,数据转成字节流。

序列化是一种对对象的深拷贝,对象如果要传输或者保存,需要先序列化成字节序,再按照一定的编码规则保存,读取反之。

编解码是机器和人类的交流,字节序和人类语言的翻译器。

序列化是机器码和进程语言的翻译器。

包括人类语言,也分为实词和虚词,实词就是操作数,虚词就是操作码。按照一定的流程规则-语法,构成了一句话-指令。

编解码针对的是内存中文本或者数字格式的数据,序列化针对的是内存中含有抽象数据类型,比如指针,这种累心该数据的保存或者传输。嗯~我就是这么理解的


什么是序列化,为什么要序列化

以下序列化机制的解决方案:
1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)
2.当要保存一个对象时,先检查该对象是否被保存了。
3.如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象
通过以上的步骤序列化机制解决了对象引用的问题
序列化的实现
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然也不可被恢复。但有时我们想将某一字段序列化,但它在SDK中的定义却是不可序列化的类型,这样的话我们也必须把他标注为transient


在学习分布式计算的时候,老师上课提到序列化这个概念。当时有些懵逼,不知道

什么是序列化,下来查了一下,原来在Java里面,序列化就是和Serializable接口相关的

东西。

 

以下是我从网上找到的关于,什么是序列化,为什么要序列化解释的比较好的一篇博文。

======================================================================分割线

简单来说序列化就是一种用来处理对象流的机制。所谓对象流也就是将对象的

内容进行流化,流的概念这里不用多说(就是I/O)。我们可以对流化后的对象进行读写

操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)!

在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!

-----------------------------------------------------------------------------------------小分割线
问题的引出:
如上所述,读写对象会有什么问题呢?比如:我要将对象写入一个磁盘文件而后再将

其读出来会有什么问题吗?别急,其中一个最大的问题就是对象引用!

举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,

现在我们对两个类进行实例化{ A a = new A(); B b = new B(); }。这时在内存中实际上分配

了两个空间,一个存储对象a,一个存储对象b。接下来我们想将它们写入到磁盘的一个文件

中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a

的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,

内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a

的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!

https://blog.csdn.net/u011215133/article/details/51177843/


人类认识文字,计算机认识机器码,是计算机存储时候用的。编码解码是人类语言,和机器语言的翻译规则。

序列化,是计算机持久化或者传输数据需要   序列化和编码解码;是两个维度的概念~~~

序列化是 对象---字符串即字节序(序列化:把对象转换为字节序列的过程称为对象的序列化。如protobuf和gob,都是序列化工具。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。),编码是 字符串--机器码???

编码解码是机器码对应的字符,序列化与反序列化是一块内存中的线性序列如对象,表示成字符???

编码和序列化是一个东西,都是内存中的表示,转换成二进制,在存储传输数据的过程中,都必须把内存中的数据转换成二进制数据。???

我认为:编码是文本对二进制的转换,而序列化是对象对二进制的转换。?对吗

序列化: 就是将内存中的对象转换为字节序列,方便持久化到磁盘或者网络传输。

对象序列化过程可以分为两步:
第一: 将对象转换为字节数组
第二: 将字节数组存储到磁盘


对象序列化:它是一个将任意复杂的对象转成对象的文本或二进制表示的过程。

  • 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
  • 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化。

 

 

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式


https://blog.csdn.net/wyxhd2008/article/details/7888061

1、序列化

序列化是通常用来描述将一个对象结构转换成一个字节数组过程的规则。这对于表达对象的状态非常有用。序列化可以用来将一个对象的状态持续保存到一个文件或者一个数据库中,拷贝一个对象到粘贴板,或者通过网络将对象传递给其他应用程序。但WCF与序列化的标准定义不同。WCF定义序列化作为将一个对象结构转换成一个XML信息集(XML Infoset)的过程.

2、编码

编码是用来描述将一个WCF消息转换成一个字节数组的规则。这样便于消息在一个传输协议上通信。WCF提供了5种编码格式类型: 二进制,文本,消息转换优化架构(MTOM),JavaScript 对象标记(JSON)和普通原有XML(POX)
 对像-msg是序列化--机器码 是编码???


因为计算机中只可以存储0-1形式的机器码,其实0-1对应的就是计算机硬件中一个开关的打开与闭合。对于编程人员来说,用0-1这种机器码去写程序显然是很不友好的,于是就出现了编程语言,编程语言是一些我们可以看懂的字符,它极大的解放了编程人员,但是另一方面对人类友好也就意味着对机器不友好,计算机是不认识这些字符的,所以自然而然编码和解码就登上了历史的舞台。
 ———————————————— 
我认为就是人类语言和机器语言的桥梁~编码;ASCII码是美国人的语言对应的机器码。

Unicode只规定了字符对应的二进制数据,但是没有规定这种二进制数据在内存中具体用几个字节存储;

Bytes:网络数据传输中唯一的数据格式,什么Json,Xml这些格式的字符串最后想传输也都得转成Bytes的数据类型才能通过socket进行传输,而Bytes的数据与字符串类型数据的转换就是编码与解码的转换,utf-8是编解码时指定的格式;

引言

       每次坐下来写一篇博客总结的时候都会先长长的舒一口气,从被一个问题困扰开始,到最后搞清楚弄明白原理,其间经历的过程就像从窒息的环境中慢慢恢复呼吸。作为一个计算机专业的学生,大学四年的时间竟然从没仔细思考过编码与解码的细节是惭愧的,只记得当年老师讲过的一条真理:”遇到编码的问题统一选utf8就好了”。知其然不知其所以然,我曾无数次鄙视过我的灵魂,此时此刻就是无数次中的一次。

字符编码的由来

       字符编码的历史网上有很多篇文章介绍,其实弄明白了这些关于编码的困惑也就解决一多半了,下面我试着看看能否可以解释清楚。

       我们知道计算机的发明者是美国的大佬们,从计算机出现的那天起关于编码的问题也就伴随着出现了。因为计算机中只可以存储0-1形式的机器码,其实0-1对应的就是计算机硬件中一个开关的打开与闭合。对于编程人员来说,用0-1这种机器码去写程序显然是很不友好的,于是就出现了编程语言,编程语言是一些我们可以看懂的字符,它极大的解放了编程人员,但是另一方面对人类友好也就意味着对机器不友好,计算机是不认识这些字符的,所以自然而然编码和解码就登上了历史的舞台。

      最先出现的编码格式是ASCII码,这种编码规则是美国人制定的,大致的规则是用一个字节(8个bit)去表示出现的字符,其实由于在老美的世界里中总共出现的字符也不超过128个,而一个字节能够表示256种字符,所以当时这种编码的方式是没有问题的。

      后来计算机在全世界普及起来,不同国家的语言都面临着如何在计算机中表示的问题,比如我们的汉字常用的就有几千个,显然最开始一个字节的ASIIC码表示就不够用了,这个时候就出现了Unicode编码,确切的说它只是一种表示规则,并不对应具体的实现形式。Uni-这个前缀在英文中表示的是统一的含义,它试图把全世界的语言用一种统一的编码表示,但是Unicode只规定了字符对应的二进制数据,但是没有规定这种二进制数据在内存中具体用几个字节存储,然后就乱套了,各国在实现Unicode时都发挥了自己的聪明才智,出现了类似utf-16,utf-32等等的形式,在这种情况下,Unicode的理想并没有实现,直到互联网的普及,utf-8的出现,utf-8的出现真正实现了大一统,它在实现Unicode规范的同时,又扩展了自己的规则,utf-8规定了任意一种字符编码后的机器码都是占用6个字节。

关于Bytes

      很多人在这里有个误会,就是容易把Bytes和编程语言里的其它数据类型混淆,其实Bytes才是计算机里真正的数据类型,也是网络数据传输中唯一的数据格式,什么Json,Xml这些格式的字符串最后想传输也都得转成Bytes的数据类型才能通过socket进行传输,而Bytes的数据与字符串类型数据的转换就是编码与解码的转换,utf-8是编解码时指定的格式。

      这里再简单说一下序列化与反序列化,序列化可以分为本地和网络,对于本地序列化,往往就是将内存中的对象持久化到本地的硬盘,此时序列化做的工作就是将对象和一些对象的相关信息序列化成字符串,然后字符串以某种格式(比如utf-8)进行编码变成bytes类型,存储到硬盘。反序列化就是先将硬盘中的bytes类型中的数据读到内存经过解码变成字符串,然后对字符串进行反序列化解析生成对象。

      网络中传输的数据一般为Json和Xml,此时序列化是指将对象变成Json类型的字符串,传输时同样需要将序列化后的字符串变成Bytes类型,反序列化是先将拿到的Bytes类型的数据变成Json类型的字符串(这一步框架往往会帮我们做),然后真正的反序列化是指将Json类型的字符串变成Json类型的对象。(这里注意区分Json类型的字符串和Json类型的对象)

最后

      最后还是想再强调一下,不要把序列化和反序列化与编码和解码的问题混淆,这是两个不同维度的概念,如果暂时不太理解编解码的问题也不要着急,遇到程序中的编码问题时记得多思考一下就好了
 ———————————————— 
版权声明:本文为CSDN博主「AlgoLin」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kobebryantlin0/article/details/77418358


序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

目的

编辑

1、以某种存储形式使自定义对象持久化

2、将对象从一个地方传递到另一个地方。

3、使程序更具维护性。


Python 中的 Bytes 字节类型是存储在硬盘上的二进制数据, 是由 unicode 数据经过编码得来, 用于存储和传输. ( 正如食物需要密封后才能保存和传输 )

unicode 数据, 是计算机内存中统一使用的数据类型, 是内存中运行的程序能够 "理解" 的数据, 由 二进制 数据解码而来. ( 正如密封的食物需要解封才能食用 )

我认为 unicode数据是罐头,bytes字节类型是食物,是存在硬盘上的二进制数据。

二进制数据 数据和 unicode 数据之间, 存在着编码解码的对应关系. 在传输和写入数据到硬盘时, 都需要进行编码的操作. 在读取数据时, 需要进行解码的操作.

常见的 ASCII, UTF-8, GBK 都是在unicode数据和二进制数据的转换过程中所使用的编码.

默认地, 在读写文件时, 程序会根据当前计算机系统使用的字符编码来确定编码解码时使用的"字典".

解码:

在读取硬盘文件的时候, 软件根据当前环境使用的字符集 ("字典")将硬盘上的二进制数据解码 ("翻译") 为unicode数据.

编码:

在存储数据到硬盘上的时候, 软件会根据字符集将unicode数据编码为二进制数据.

在网络传输数据的时候, 传递的也都是二进制数据.


在HTTP的响应中指示浏览器数据使用的字符集:

网络运输时的序列化和反序列化 - 食物的密封和拆封

序列化

序列化是将内存中的数据 (unicode数据) 变成可存储传输数据(二进制数据) 的过程.
在通过网络传输数据的时候, 我们需要首先将数据进行序列化处理.

反序列化:

获取到响应数据时, 需要对数据进行反序列化处理.

字符编码的应用场景:

了解了序列化和反序列化之后, 我们就可以很容易地理解那些需要转换数据类型的场景:

  • Python server socket 和 client socket 之间的数据交互:
    socket.send() 只能发送bytes数据
  • 前端使用 Ajax 和服务器交互时需要序列化数据.
  • 向文件写入数据, 读取文件时都需要指定编码格式.



作者:Apolo_Du
链接:https://www.jianshu.com/p/8bd842bf1de7
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/u013755520/article/details/99938337
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2019-08-27 16:35:39
  • 阅读 ( 1269 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢