Vấn đề tôi gặp phải là: không phải tất cả các biến (có thể là nguyên thủy như các đối tượng int hoặc composite) đã được biểu diễn bằng một chuỗi byte?
Vâng, họ là. Vấn đề ở đây là cách bố trí các byte đó. Một đơn giản int
có thể dài 2, 4 hoặc 8 bit. Nó có thể ở endian lớn hoặc nhỏ. Nó có thể không được ký, ký với phần bổ sung 1 hoặc thậm chí trong một số mã hóa siêu kỳ lạ như negabinary.
Nếu bạn chỉ bỏ rác một cách int
ngẫu nhiên từ bộ nhớ và gọi nó là "tuần tự hóa", bạn phải đính kèm khá nhiều toàn bộ máy tính, hệ điều hành và chương trình của bạn để nó có thể khử được. Hoặc ít nhất, một mô tả chính xác về họ.
Vì vậy, những gì làm cho serialization như một chủ đề sâu sắc? Để tuần tự hóa một biến, chúng ta có thể lấy các byte này trong bộ nhớ và ghi chúng vào một tệp không? Những gì phức tạp tôi đã bỏ lỡ?
Việc tuần tự hóa một đối tượng đơn giản là viết ra nó theo một số quy tắc. Những quy tắc đó rất nhiều và không phải lúc nào cũng rõ ràng. Ví dụ: một xs:integer
XML được viết trong cơ sở 10. Không phải cơ sở-16, không phải cơ sở-9, nhưng 10. Đây không phải là một giả định ẩn, đó là một quy tắc thực tế. Và các quy tắc như vậy làm cho tuần tự hóa một tuần tự. Bởi vì, khá nhiều, không có quy tắc nào về cách bố trí bit của chương trình của bạn trong bộ nhớ .
Đó chỉ là một đỉnh của tảng băng trôi. Hãy lấy một ví dụ về một chuỗi những nguyên thủy đơn giản nhất: a C struct
. Bạn có thể nghĩ rằng
struct {
short width;
short height;
long count;
}
có bố cục bộ nhớ xác định trên một máy tính nhất định + HĐH không? Vâng, nó không. Tùy thuộc vào #pragma pack
cài đặt hiện tại , trình biên dịch sẽ đệm các trường. Trên cài đặt mặc định của trình biên dịch 32 bit, cả hai shorts
sẽ được đệm thành 4 byte để struct
thực sự sẽ có 3 trường 4 byte trong bộ nhớ. Vì vậy, bây giờ, bạn không chỉ phải xác định short
dài 16 bit, đó là một số nguyên, được viết bằng 1 bổ sung âm, cuối hoặc lớn. Bạn cũng phải ghi lại cài đặt đóng gói cấu trúc mà chương trình của bạn được biên dịch.
Đó là khá nhiều những gì nối tiếp là về: tạo ra một bộ quy tắc và tuân theo chúng.
Các quy tắc đó sau đó có thể được mở rộng để chấp nhận các cấu trúc phức tạp hơn (như danh sách độ dài thay đổi hoặc dữ liệu phi tuyến), các tính năng được thêm vào như khả năng đọc của con người, phiên bản, khả năng tương thích ngược và sửa lỗi, v.v. Nhưng ngay cả việc viết ra một đơn int
cũng đủ phức tạp nếu bạn chỉ muốn chắc chắn rằng bạn sẽ có thể đọc lại một cách đáng tin cậy.