CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.
Bài viết blog CFSDN này nói sơ qua về serialization và deserialization trong .Net, được tác giả sưu tầm và biên soạn. Nếu bạn quan tâm tới bài viết này thì nhớ like nhé.
Tôi tin rằng mọi người thường nghe nói về tuần tự hóa và giải tuần tự hóa và sử dụng nó. Tuy nhiên, một số người có thể không biết: tại sao .net lại có thứ này và làm thế nào .net frameword triển khai cơ chế như vậy cho chúng ta. tuần tự hóa và giải tuần tự hóa.
1. Tuần tự hóa và giải tuần tự hóa là gì.
Theo thuật ngữ của giáo dân, tuần tự hóa là quá trình chuyển đổi một đối tượng thành luồng byte để có thể dễ dàng lưu nó vào tệp đĩa hoặc cơ sở dữ liệu. Deserialization là quá trình tuần tự hóa ngược lại, là quá trình chuyển đổi luồng byte trở lại đối tượng ban đầu.
Nhưng tại sao chúng ta cần các cơ chế như tuần tự hóa và giải tuần tự hóa? Câu hỏi này cũng liên quan đến việc sử dụng tuần tự hóa và giải tuần tự hóa.
Các ứng dụng chính của việc tuần tự hóa là:
- Lưu trạng thái của ứng dụng vào tệp đĩa hoặc cơ sở dữ liệu và khôi phục trạng thái vào lần chạy ứng dụng tiếp theo. Ví dụ: tuần tự hóa và giải tuần tự hóa được sử dụng trong ASP.NET để lưu và khôi phục trạng thái phiên.
- Có thể dễ dàng sao chép một tập hợp các đối tượng vào khay nhớ tạm của Windows Forms và dán lại vào cùng một ứng dụng hoặc ứng dụng khác.
- Gửi các đối tượng theo giá trị từ miền ứng dụng này sang miền ứng dụng khác
Và nếu đối tượng được tuần tự hóa thành luồng byte trong bộ nhớ, một số công nghệ khác có thể được sử dụng để xử lý dữ liệu, chẳng hạn như mã hóa và nén dữ liệu.
2. Việc tuần tự hóa và giải tuần tự hóa rất dễ sử dụng.
.net framework cung cấp hai phương thức tuần tự hóa:
- tuần tự hóa nhị phân
- tuần tự hóa xml và xà phòng
Sử dụng đơn giản tuần tự hóa và giải tuần tự hóa:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
sử dụng
hệ thống;
sử dụng
hệ thống.io;
sử dụng
system.runtime.serialization.formatters.binary;
không gian tên
có thể tuần tự hóa
{
[có thể tuần tự hóa]
công cộng
lớp học
người
{
công cộng
sợi dây
tên người;
[không tuần tự]
công cộng
sợi dây
chiều cao người;
riêng tư
số nguyên
nhân vật;
công cộng
số nguyên
nhân vật
{
lấy
{
trở lại
nhân vật; }
bộ
{ nhân vật = giá trị; }
}
công cộng
vô hiệu
viết()
{
console.writeline(
"tên người: "
+tên người);
console.writeline(
"chiều cao của người: "
+chiều cao người);
console.writeline(
"tuổi của người: "
+ nhân vật);
}
}
lớp học
chương trình
{
tĩnh
vô hiệu
chủ yếu(
sợi dây
[] đối số)
{
người người =
mới
người();
person.personname =
"Jerry"
;
person.personheight =
"175cm"
;
person.personage = 22;
luồng luồng = tuần tự hóa(người);
luồng.vị trí = 0;
người =
vô giá trị
;
người = deserialize(stream);
person.write();
console. đọc();
}
riêng tư
tĩnh
memorystream tuần tự hóa(người người)
{
luồng bộ nhớ =
mới
luồng bộ nhớ();
định dạng nhị phân định dạng nhị phân =
mới
trình định dạng nhị phân();
binaryformatter.serialize(luồng, người);
trở lại
suối;
}
riêng tư
tĩnh
người hủy tuần tự hóa (luồng luồng)
{
định dạng nhị phân định dạng nhị phân =
mới
trình định dạng nhị phân();
trở lại
(người)binaryformatter.deserialize(stream);
}
}
}
|
Nó chủ yếu gọi lớp binnaryformatter trong không gian tên system.runtime.serialization.formatters.binary để thực hiện tuần tự hóa và giải tuần tự hóa.

Có thể thấy, ngoại trừ các thành viên được đánh dấu là nonserialized, các thành viên khác có thể được serialized. Lưu ý rằng thuộc tính này chỉ có thể áp dụng cho các trường thuộc một loại và sẽ được kế thừa bởi các loại dẫn xuất.
Việc tuần tự hóa và giải tuần tự hóa của xà phòng và xml cũng tương tự như trên. Bạn chỉ cần thay đổi bộ định dạng tôi sẽ không liệt kê chúng ở đây.
3. Kiểm soát việc tuần tự hóa và giải tuần tự hóa.
Có hai cách để triển khai tuần tự hóa và giải tuần tự hóa điều khiển:
- 通过onserializing, onserialized, ondeserializing, ondeserialized, nonserialized và optionalfield
- Triển khai giao diện system.runtime.serialization.iserializable
Cách đầu tiên để triển khai mã tuần tự hóa và giải tuần tự hóa điều khiển:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
sử dụng
hệ thống;
sử dụng
hệ thống.io;
sử dụng
system.runtime.serialization;
sử dụng
system.runtime.serialization.formatters.binary;
không gian tên
kiểm soát tuần tự hóa
{
[có thể tuần tự hóa]
công cộng
lớp học
vòng tròn
{
riêng tư
gấp đôi
bán kính;
[không tuần tự]
công cộng
gấp đôi
khu vực;
công cộng
vòng tròn(
gấp đôi
bán kính đầu vào)
{
bán kính = bán kính đầu vào;
diện tích = math.pi * bán kính * bán kính;
}
[không tuần tự hóa]
riêng tư
vô hiệu
ondeserialized(streamingcontext ngữ cảnh)
{
diện tích = math.pi * bán kính * bán kính;
}
công cộng
vô hiệu
viết()
{
console.writeline(
"bán kính là: "
+ bán kính);
console.writeline(
"diện tích là: "
+ diện tích);
}
}
lớp học
chương trình
{
tĩnh
vô hiệu
chủ yếu(
sợi dây
[] đối số)
{
vòng tròn c =
mới
vòng tròn(10);
luồng bộ nhớ =
mới
luồng bộ nhớ();
binaryformatter định dạng =
mới
trình định dạng nhị phân();
formatter.serialize(luồng,c);
luồng.vị trí = 0;
c =
vô giá trị
;
c = (hình tròn)formatter.deserialize(luồng);
c. write();
console. đọc();
}
}
}
|
Kết quả chạy là:

Lưu ý: Nếu thuộc tính ondeserialized được nhận xét, giá trị của trường khu vực sẽ là 0, vì trường khu vực không được tuần tự hóa vào luồng.
Trong đối tượng trên cần được tuần tự hóa, trình định dạng sẽ chỉ tuần tự hóa giá trị của trường bán kính của đối tượng. Giá trị trong trường khu vực sẽ không được tuần tự hóa vì thuộc tính nonserializedattribute đã được áp dụng cho trường. Sau đó, khi chúng ta xây dựng một đối tượng vòng tròn có mã như vòng tròn c=vòng tròn mới (10), bên trong, khu vực sẽ đặt giá trị khoảng 314.159. . Giá trị, khi đối tượng này được tuần tự hóa, chỉ giá trị của trường bán kính (10) được ghi vào luồng. Nhưng khi được giải tuần tự hóa thành một đối tượng hình tròn, giá trị của trường diện tích của nó sẽ được khởi tạo thành 0 thay vì giá trị xấp xỉ 314.159. Để giải quyết vấn đề này, một phương thức tùy chỉnh được sử dụng để áp dụng thuộc tính ondeserializedattribute. Quá trình thực thi tại thời điểm này là: mỗi khi một phiên bản của loại được giải tuần tự hóa, trình định dạng sẽ kiểm tra xem một phương thức áp dụng thuộc tính có được xác định trong loại hay không. Nếu vậy, phương thức đó sẽ được gọi. Các trường được tuần tự hóa có sẵn sẽ được đặt chính xác. Ngoài thuộc tính tùy chỉnh ondeserializedattribute, không gian tên system.runtime.serialization cũng xác định các thuộc tính tùy chỉnh onserializingattribute, ondeserializedattribute và ondeserializingattribute.
Triển khai giao diện có thể tuần tự hóa để kiểm soát mã tuần tự hóa và giải tuần tự hóa:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
sử dụng
hệ thống;
sử dụng
hệ thống.io;
sử dụng
system.runtime.serialization;
sử dụng
system.runtime.serialization.formatters.binary;
sử dụng
hệ thống.bảo mật.quyền;
không gian tên
kiểm soát việc chuẩn hóa2
{
[có thể tuần tự hóa]
công cộng
lớp học
myobject : có thể tuần tự hóa
{
công cộng
số nguyên
n1;
công cộng
intn2;
[không tuần tự]
công cộng
sợi dây
đường;
công cộng
đối tượng của tôi()
{
}
được bảo vệ
myobject(thông tin serializationinfo, ngữ cảnh streamingcontext)
{
n1 = info.tint32(
"Tôi"
);
n2 = info.tint32(
"j"
);
str = info.getstring(
"k"
);
}
[securitypermissionattribute(securityaction.demand, serializationformatter =
ĐÚNG VẬY
)]
công cộng
ảo
vô hiệu
getobjectdata(thông tin serializationinfo, ngữ cảnh streamingcontext)
{
thông tin.addvalue(
"Tôi"
, n1);
thông tin.addvalue(
"j"
, n2);
thông tin.addvalue(
"k"
, chuỗi);
}
công cộng
vô hiệu
viết()
{
console.writeline(
"n1 là: "
+ n1);
console.writeline(
"n2 là: "
+n2);
console.writeline(
"str là: "
+ chuỗi);
}
}
lớp học
chương trình
{
tĩnh
vô hiệu
chủ yếu(
sợi dây
[] đối số)
{
đối tượng của tôi obj =
mới
đối tượng của tôi();
obj.n1 = 2;
obj.n2 = 3;
obj.str =
"Jeffy"
;
luồng bộ nhớ =
mới
luồng bộ nhớ();
binaryformatter định dạng =
mới
trình định dạng nhị phân();
formatter.serialize(luồng, obj);
luồng.vị trí = 0;
đối tượng =
vô giá trị
;
obj = (myobject)formatter.deserialize(luồng);
obj.write();
console. đọc();
}
}
}
|
Kết quả là:

Quá trình thực hiện tại thời điểm này là: khi trình định dạng tuần tự hóa đối tượng, nó sẽ kiểm tra từng đối tượng. Nếu phát hiện thấy loại đối tượng triển khai giao diện có thể tuần tự hóa, trình định dạng sẽ bỏ qua tất cả các thuộc tính tùy chỉnh và thay vào đó xây dựng một hệ thống mới. Đối tượng run.serialization.serializationinfo, đối tượng này chứa tập hợp các giá trị sẽ được tuần tự hóa thực sự cho đối tượng. Sau khi đối tượng serializationinfo được xây dựng và khởi tạo, trình định dạng gọi phương thức getobjectdata của loại và chuyển nó tham chiếu đến đối tượng serializationinfo. Phương thức getobjectdata chịu trách nhiệm xác định thông tin nào cần thiết để tuần tự hóa đối tượng và thêm thông tin này vào serializationinfo. đối tượng. Thêm từng dữ liệu cần thiết bằng cách gọi phương thức addvalue. , sau khi thêm tất cả thông tin tuần tự hóa cần thiết, nó sẽ được trả về trình định dạng và sau đó trình định dạng sẽ nhận tất cả các giá trị đã được thêm vào đối tượng serializationinfo và tuần tự hóa chúng vào luồng. Khi trình định dạng giải nén, định dạng sẽ được trích xuất. một đối tượng từ luồng, nó sẽ phân bổ bộ nhớ cho đối tượng mới. Ban đầu, tất cả các trường của đối tượng này được đặt thành 0 hoặc null. Sau đó, trình định dạng sẽ kiểm tra xem loại đó có thực hiện giao diện có thể tuần tự hóa hay không. Trình định dạng cố gắng gọi một hàm tạo đặc biệt có các tham số giống hệt với các tham số của phương thức getObjectData.
4. Cách trình định dạng tuần tự hóa và giải tuần tự hóa.
Như có thể thấy từ phân tích ở trên, trình định dạng chịu trách nhiệm chính cho việc tuần tự hóa và giải tuần tự hóa. Tuy nhiên, sau đây là về cách trình định dạng tuần tự hóa một đối tượng với thuộc tính serializableattribute được áp dụng.
- Trình định dạng gọi phương thức getserializablemembers của dịch vụ định dạng: public static memberinfo[] getserializablemembers(type type, streamingcontext context); phương thức này sử dụng phát xạ để thu được các trường triển khai công khai và riêng tư của loại (ngoại trừ các trường được đánh dấu bằng thuộc tính nonserializedattributee). Phương thức này trả về một mảng các đối tượng memberinfo, trong đó mỗi phần tử tương ứng với một trường phiên bản có thể tuần tự hóa.
- Đối tượng được tuần tự hóa và mảng đối tượng system.reflection.memberinfo được truyền tới phương thức tĩnh getobjectdata của dịch vụ định dạng: public static object[] getobjectdata(object obj, memberinfo[] member); được xác định Giá trị của một trường trong đối tượng được tuần tự hóa.
- Trình định dạng ghi ID tập hợp và tên đầy đủ của loại vào luồng.
- Sau đó, trình định dạng sẽ lặp lại các phần tử trong cả hai mảng, ghi tên và giá trị của từng thành viên vào luồng.
Tiếp theo là giải thích về cách trình định dạng tự động giải tuần tự hóa một đối tượng khi áp dụng thuộc tính serializableattribute.
- Trình định dạng đọc ID tập hợp và tên loại đầy đủ từ luồng.
- Trình định dạng gọi phương thức tĩnh getuninitializedobject của dịch vụ định dạng: đối tượng tĩnh công khai getuninitializedobject(type ttype); Phương thức này phân bổ bộ nhớ cho một đối tượng mới, nhưng không gọi hàm tạo cho đối tượng. Tuy nhiên, tất cả các trường của đối tượng được khởi tạo bằng 0 hoặc null.
- Trình định dạng hiện xây dựng và khởi tạo một mảng thông tin thành viên và gọi phương thức geterializablemembers của dịch vụ định dạng. Phương thức này trả về một tập hợp các trường đã được tuần tự hóa và bây giờ cần được giải tuần tự hóa.
- Trình định dạng tạo và khởi tạo một mảng đối tượng dựa trên dữ liệu có trong luồng.
- Truyền các tham chiếu đến đối tượng mới được phân bổ, mảng thông tin thành viên và mảng đối tượng song song cho phương thức tĩnh populateobjectmembers của dịch vụ định dạng:
public static object populateobjectmembers(object obj, memberinfo[] member, object[] data); Phương thức này duyệt mảng và khởi tạo từng trường với giá trị tương ứng.
Lưu ý: Phần về định dạng cách tuần tự hóa và giải tuần tự hóa các đối tượng được trích từ clr qua C# (ấn bản thứ ba). Được viết ở đây có thể cho phép người mới bắt đầu hiểu rõ hơn về công việc được thực hiện bởi trình định dạng trong quá trình tuần tự hóa và giải tuần tự hóa.
Đến đây, bài viết về tuần tự hóa và giải tuần tự hóa này cuối cùng đã kết thúc. Tôi hy vọng nó sẽ hữu ích cho những đánh giá trong tương lai của tôi và những người bạn trong vườn.
Trên đây là phần thảo luận ngắn gọn về chi tiết của tuần tự hóa và giải tuần tự hóa trong .net. Để biết thêm thông tin về tuần tự hóa và giải tuần tự hóa .net, vui lòng chú ý đến các bài viết liên quan khác của tôi! .
Liên kết gốc: https://www.kancloud.cn/wizardforcel/learning-hard-csharp/111555.
Cuối cùng, bài viết về tuần tự hóa và giải tuần tự hóa trong .Net kết thúc tại đây. Nếu bạn muốn biết thêm về tuần tự hóa và giải tuần tự hóa trong .Net, vui lòng tìm kiếm bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan. tương lai! .
Tôi là một lập trình viên xuất sắc, rất giỏi!