Python3学习(33)--序列和反序列化(二)
来源:互联网 发布:快压压缩软件 编辑:程序博客网 时间:2024/06/05 04:32
上一篇,我们遗留了一个问题,那就是Python的pickle模块,序列化后的字节流bytes,如果通过socket传给Java,Java可以反序列化吗?
我们看下demo案列(案列很简单,就是简单的信息传输,不涉及多线程和回写),验证一下就知道了:
Java服务端demo
import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.net.ServerSocket;import java.net.Socket;public class Test2 { public static void main(String[] args){ ServerSocket serverSocket;try {serverSocket = new ServerSocket(9999);System.out.println("等待连接.......");Socket socket;socket = serverSocket.accept();//一直阻塞System.out.println("客户端已连接!");InputStream ins = socket.getInputStream();InputStreamReader isr = new InputStreamReader(ins,"utf-8");BufferedReader bReader = new BufferedReader(isr);String line = "";StringBuffer buffer = new StringBuffer();while(!("==END==").equals(line=bReader.readLine())){System.out.println("客户端:"+line);buffer.append(line+"\n");}System.out.println("接收到的完整buffer:"+buffer.toString());ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); String str = new String(buffer); oos.writeObject(str); byte [] strData = baos.toByteArray();ByteArrayInputStream baoi = new ByteArrayInputStream(strData);ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(baoi));try {Object Obj = ois.readObject();System.out.println(Obj.getClass());System.out.println("对象反序列化成功!");} catch (ClassNotFoundException e) {e.printStackTrace();} finally {serverSocket.close();socket.close();ins.close();isr.close();baos.close();baoi.close();oos.close();} } catch (IOException e) {e.printStackTrace();} }}
Python客户端demo
#!/usr/bin/env Python3# -*- encoding:utf-8 -*-import socket,pickleclass Employee: def __init__(self,name,sex,age,salary): self.name = name #姓名 self.sex = sex #性别 self.__age = age #年龄 私有变量 self.salary= salary #薪资 按月算 @property def age(self): #age的getter属性,还记得装饰器@property的用法吗? return self.__age @age.setter def age(self,value): #age的setter属性 self.__age = value def add(self,a,b): return a+bperson = Employee('张三','男',35,6000.00)s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(('127.0.0.1',9999)) s.send(pickle.dumps(person)+bytes('\n==END==\n',encoding='utf-8'))
运行客户端,由于客户端没有接收部分,所以,我们直接看Java服务端
为了使Java服务端正常的运作,耍了一下小聪明,我们用Python传过来的字节流初始化了一个String对象str,因为谁也没告诉我,Python传过来的字节流里面装的究竟是啥(一堆乱码,我Java一脸懵逼),我就假设一下是字符串对象,显然,字符串对象序列化后,在反序列化后仍然是字符串,也就是Python传过来的内容,我Java这边只能胡乱猜测,猜测的结果就是又绕回去了。这就牵扯到了不同语言之间的序列化共性问题了,也就是你Python序列化后的字节流,你自己清楚该怎么反序列回去,而我Java则是按照自己的序列化规则走,因此,就导致,双方无法通过序列化后的字节流进行交流。
我们看下,Python是不是可以识别这些"乱码"
在Python中用pickle.load反序列1.txt里面的内容,还原对象如下
这就让人不淡定了,那我怎么让Python的对象序列化后的内容分享给Java,让Java也能看到呢?
记住,不管你是哪种编程语言,你肯定能识别字符串对吧,基本数据类型啊,连这都识别不了,你想干嘛,是不是想上上天啊?
好了,既然是字符串,结合上一篇所讲,在Python中,我们引入json模块,使用dumps函数将对象序列化成json串,然后,我们拿这个json串再交给Java,Java不就能识别了嘛,而且,Java还能对json串进行详细的解析,不信吗?不信,我们就来看一下demo案列:
服务端依然由Java来接收(Java需要引入相关的Jar包,这里是讲Python,Java不是重点):
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import com.google.gson.JsonArray;import com.google.gson.JsonObject;import com.google.gson.JsonParser;public class ServerTest {public static void main(String[] args) { try {ServerSocket serverSocket = new ServerSocket(9999);System.out.println("等待连接.......");Socket socket = serverSocket.accept();//一直阻塞System.out.println("客户端已连接!");//如果连上了 执行下面的语句//读取输入流 看看客户端说了什么InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is,"GBK");BufferedReader bReader = new BufferedReader(isr);String line = "";while(!"==END==".equals(line =bReader.readLine())){System.out.println("客户端:"+line); JsonParser parser=new JsonParser(); //创建JSON解析器 JsonObject object=(JsonObject) parser.parse(line); //创建JsonObject对象 JsonArray array=object.get("data").getAsJsonArray(); //得到为json的数组 for(int i=0;i<array.size();i++){ System.out.println("---------------"); JsonObject subObject=array.get(i).getAsJsonObject(); System.out.println("name="+subObject.get("name").getAsString()); System.out.println("sex="+subObject.get("sex").getAsString()); // System.out.println("age"+subObject.get("_Employee__age").getAsString()); System.out.println("age="+subObject.get("age").getAsString()); System.out.println("sum="+subObject.get("sum").getAsInt()); }}socket.shutdownInput();//关闭输入流//响应连接用户信息OutputStream os = socket.getOutputStream();PrintWriter writer = new PrintWriter(os);writer.write("服务端: "+socket.getInetAddress().toString().replaceAll("/", "")+",您好!你传过来的JSON数据,我已成功接收并解析。");writer.flush(); writer.close(); os.close(); bReader.close(); isr.close(); is.close(); socket.close();} catch (IOException e) {e.printStackTrace();} }}
启动服务端
客户端由我们的Python来处理数据(demo和上一篇如出一辙,就不细说了)
#!/usr/bin/env Python3# -*- encoding:utf-8 -*-import socket,pickle,jsonclass Employee: def __init__(self,name,sex,age,salary): self.name = name #姓名 self.sex = sex #性别 self.__age = age #年龄 私有变量 self.salary= salary #薪资 按月算 @property def age(self): #age的getter属性,还记得装饰器@property的用法吗? return self.__age @age.setter def age(self,value): #age的setter属性 self.__age = value def add(self,a,b): return a+bp1 = Employee('张三','男',35,6000.00)#动态绑定实例的属性变量p1.a = 4p1.b = 5p2 = Employee('李婷','女',25,4000.00)p2.a = 10p2.b = 20p3 = Employee('王五','男',30,5000.00)p3.a = 11p3.b = 25L=[]L.append(p1)L.append(p2)L.append(p3)def ToJson(obj): return { 'name' :obj.name, 'sex' :obj.sex , 'age' :obj.age , 'salary':obj.salary, 'sum' :obj.add(obj.a,obj.b) } data = json.dumps(L,default=ToJson)s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(('192.168.1.54',9999)) #s.send(bytes(data,encoding='utf-8'))data = '{ "data":'+data+'}'s.send(bytes(data+'\n==END==\n',encoding='utf-8'))buff = []while True: b = s.recv(1024) if b: buff.append(b) else: break; for msg in buff: #print(msg.decode('utf-8')) print(msg.decode('gb2312'))s.close()
运行客户端,走你(不要注重demo,主要看效果)
服务端
Java处理完Python发过来的json数据之后,会告诉Python,兄弟,谢谢你啊,数据我收到了!当然,这是我说的。
客户端
本篇是对上一篇的承诺,如果我们只知道Python有个序列化和反序列化,而不知道怎么用的话,或者,我们就是自己跟自己玩,这种情况,完全不必担心反序列化会出问题,照着函数用就行;万一,让你和其他语言一起玩,你是不是就愣住了,这时候,不要怕,只要你会用Python的json模块,你就可以跟其他语言掰掰手腕了:"你要数据是吧,没问题,扔给你一个json字符串,自己玩去吧!",
- Python3学习(33)--序列和反序列化(二)
- Python3学习(32)--序列和反序列化(一)
- 序列化和反序列化(二)
- python3里的序列化和反序列化
- python3序列化与反序列化
- 序列化和反序列化(二)--自定义序列化
- 序列和反序列化
- 序列和反序列化
- 序列化和反序列化( 二)
- .Net深入学习序列化和反序列化
- .Net深入学习序列化和反序列化
- IO学习(十二)序列化和反序列化
- 序列化和反序列化---学习笔记
- python 学习 -- json的序列化和反序列化
- Hadoop学习日志之序列化和反序列化
- C#序列化和反序列化之二 自定义序列化
- 序列化和反序列化
- 序列化和反序列化
- SSM框架——Spring+SpringMVC+Mybatis的搭建教程
- C语言(字母大小写的转换)
- 小白做今日头条常见问题汇总
- django bug, No module named MySQLdb
- cocos2d-x 、锚点与坐标系详解
- Python3学习(33)--序列和反序列化(二)
- 用户-角色-权限
- 学习笔记之面向对象编程21(数据流、Print流)
- hmset 与hdel 一次操作多个 fields
- js 中document.referrer
- 8大排序算法详解
- Spring中@Transactional用法深度分析之一
- maven groupId
- 个人见解:为什么说橘猫胖?