1 序列化概念
- 序列化就是一个把Java对象编码成一串二进制的过程
- 序列化的用途:可以将对象放入文件存储、或者放入网络传输
- 反序列化就是一个解码的过程
- 序列化没有固定的标准,有各种各样序列化的方法
Java自带序列化接口
- 创建一个User类
- 在main方法里创建User对象,通过ObjectOutputStream把对象写入到文件中
- 让User类实现 Serializable 接口
- 把User对象写入到文件成功!
- 我们发现写入后的文件大小比对象所有的属性值大很多
- 因为java的Serializable会把类的继承体系也写到文件里,多了很多额外的信息
- 会变得更臃肿,不利于大数据的数据在分布式系统中传输
[Actionscript3]
纯文本查看
复制代码
1
2
3
4
5
6
7
|
private
static
void
encoding() throws Exception {
ObjectOutputStream os =
new
ObjectOutputStream(
new
FileOutputStream(
"E:/test/obj1.txt"
));
SerializableUser user =
new
SerializableUser();
user.
set
(
"9521"
,
"周星星"
,
23
, 10000D);
os.writeObject(user);
os.close();
}
|
[Java]
纯文本查看
复制代码
1
2
3
4
5
6
7
|
private
static
void
decoding()
throws
Exception {
ObjectInputStream oi =
new
ObjectInputStream(
new
FileInputStream(
"E:/test/obj1.txt"
));
Object object = oi.readObject();
SerializableUser user = (SerializableUser) object;
System.out.println(user);
oi.close();
}
|
自定义序列化(FileOutputStream)
- 我们通过把对象的属性拼接成字符串
- 通过 FileOutputStream 将字符串写入文件中
- 写入后发现文件大小变小了很多(由150字节 --> 50字节)
- 反序列化的时候读取一行数据自己切割后放入对象
- 存在一个问题,如果是一个Int类型的值,它变成字符串后字节长度变长了
将对象转成 json 格式再序列化
- 通过把对象转成 json 格式序列化后可以很方便的对数据进行操作
[Java]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
|
private
static
void
encoding2()
throws
Exception {
SerializableUser user =
new
SerializableUser();
user.set(
"9521"
,
"周星星"
,
23
, 10000D);
Gson gson =
new
Gson();
String json = gson.toJson(user);
System.out.println(json);
FileOutputStream fos =
new
FileOutputStream(
"E:/test/obj2.txt"
);
fos.write(json.getBytes(
"utf-8"
));
fos.flush();
fos.close();
}
|
[Java]
纯文本查看
复制代码
1
2
3
4
5
6
7
8
|
private
static
void
decoding2()
throws
Exception {
BufferedReader br =
new
BufferedReader(
new
InputStreamReader((
new
FileInputStream(
"E:/test/obj2.txt"
))));
String json = br.readLine();
br.close();
Gson gson =
new
Gson();
SerializableUser user = gson.fromJson(json, SerializableUser.
class
);
System.out.println(user);
}
|
通过 DataOutputStream 优化上述代码
- 我们通过 DataOutputStream 把属性一个一个写入到文件
- 发现通过这种方式序列化后文件更加小了(再由50字节 --> 29字节)
- 字符串在原来长度上多2个字符,用于表示字符串的边界
[Java]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
private
static
void
encoding3()
throws
Exception {
SerializableUser user =
new
SerializableUser();
user.set(
"9521"
,
"周星星"
,
23
, 10000D);
DataOutputStream dos =
new
DataOutputStream(
new
FileOutputStream(
"E:/test/obj3.txt"
));
dos.writeUTF(user.getId());
dos.writeUTF(user.getName());
dos.writeInt(user.getAge());
dos.writeDouble(user.getSalary());
dos.flush();
dos.close();
}
|
[Java]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
|
private
static
void
decoding3()
throws
Exception {
SerializableUser user =
new
SerializableUser();
DataInputStream dis =
new
DataInputStream(
new
FileInputStream(
"E:/test/obj3.txt"
));
String id = dis.readUTF();
String name = dis.readUTF();
int
age = dis.readInt();
double
salary = dis.readDouble();
user.set(id, name, age, salary);
System.out.println(user);
dis.close();
}
|
总结
- Hadoop内部也有一套自己的序列化框架:提供了一个接口Writable
- 我们的类只要实现了Writable接口,hadoop内部就能用自己的序列化机制去序列化这个类的对象
2 服务概念
- 服务: 就是一个业务功能,变成可以通过网络进行请求
- 核心要素
- 必须有一个能接收网络请求的服务端
- 要有一个业务功能类
- 要有一套请求方和被请求方约定好的协议
- 要有一个支持该协议的客户端
[Java]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
public
class
SockerServer1 {
public
static
void
main(String[] args)
throws
IOException {
ServerSocket serverSocket =
new
ServerSocket(
8888
);
System.out.println(
"服务端启动..."
);
while
(
true
) {
Socket socket = serverSocket.accept();
System.out.println(
"服务端收到消息:"
);
InputStream is = socket.getInputStream();
BufferedReader br =
new
BufferedReader(
new
InputStreamReader(is));
String line =
null
;
while
((line = br.readLine()) !=
null
) {
System.out.println(line);
}
br.close();
}
}
}
|
[AppleScript]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
|
public
class
SocketClient
1
{
public static void
main
(
String[] args
)
throws IOException
{
Socket socket
=
new
Socket
(
"localhost"
,
8888
)
;
OutputStream os
=
socket.getOutputStream
(
)
;
BufferedWriter bw
=
new
BufferedWriter
(
new
OutputStreamWriter
(
os
)
)
;
bw.
write
(
"Hello Dog!"
)
;
bw.flush
(
)
;
bw.
close
(
)
;
}
}
|
可以通过浏览器访问,打印出HTTP协议
[Java]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
|
服务端启动...
服务端收到消息:
GET / HTTP/
1.1
Host: localhost:
8888
Connection: keep-alive
Cache-Control: max-age=
0
Upgrade-Insecure-Requests:
1
User-Agent: Mozilla/
5.0
(Windows NT
10.0
; Win64; x64) AppleWebKit/
537.36
(KHTML, like Gecko) Chrome/
71.0
.
3578.98
Safari/
537.36
Accept: text/html,application/xhtml+xml,application/xml;q=
0.9
,image/webp,image/apng,*/*;q=
0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=
0.9
,en;q=
0.8
|
web服务(restApi)
- 本质上还是socket通信
- 关键点在于,通信的协议是使用了一套全球通用的规范协议:HTTP
- 所以,服务端需要能够解析HTTP请求,能够按这种协议封装响应
- 客户端需要能够封装HTTP协议的请求,能够解析HTTP协议的响应
3 进程与线程
- 进程:操作系统级别的,程序运行空间(启动一个程序,就是一个进程;再起一个,又是一个进程)
- 线程:程序内部的执行空间(线程栈);
4 文件格式概念
- 文件格式,在最底层看来,都是一样的:二进制
- 上升一层(编码):,就可以有不同的编码
- 上升一层(数据组织结构):数据组织结构不同
行式存储
列式存储
5 迭代器
- 迭代器的意义:
- 让使用者可以不了解数据存储的细节的情况下,也能方便地取到数据
- 迭代器有一个通用的接口: Iterator
- 还可以再封装一层,实现另一个通用的接口:Iterable
- Iterable类可以通过iterator()方法获取一个Iterator对象,进行迭代
|
|