Trong việc xây dựng và thiết kế project games có nhiều tính toán, kỹ thuật và tính năng phải sử dụng file để thao tác nhằm tăng hiệu suất của chương trình, giúp lập trình viên dễ dàng đọc và viết, dễ phân tích và phát sinh.
JSON là gì?
JSON (viết tắt của JavaScript Object Notation) là 1 định dạng dùng để lưu trữ dữ liệu có cấu trúc chặt chẽ, linh hoạt, dễ đọc hiểu và dễ viết, dễ chỉnh sửa cho lập trình viên. JSON được tạo ra dựa trên cấu trúc của ngôn ngữ lập trình Javascript.
Cách thể hiện trong file JSON
Các file JSON có định dạng mở rộng là .json.
Dưới đây là 1 cách thể hiện đơn giản của JSON, phần bên trái là tên của các key, phần bên phải là giá trị của nó.
{ "hello": "STDIO", "t": true , "f": false, "n": null, "i": 123, "pi": 3.1416, "array": [1, 2, 3, 4], "keys": { "string": "JSON 1", "i": 9, } }
Để dễ hình dung hơn:
Khai báo thư viện JSON
Để có thể sử dụng các hàm của JSON cần khai báo thư viện của nó trước như sau:
#include "rapidjson/rapidjson.h" #include "rapidjson/document.h" using namespace rapidjson;
Cách đọc dữ liệu từ JSON vào chương trình
Lúc này khởi tạo biến m_document
để nhận dữ liệu của file JSON
Document m_document; ssize_t size; char* buf = (char*)FileUtils::getInstance()->getFileData(_fileName, "r", &size); string content(buf, size); m_document.Parse(content.c_str());
Phân tích:
- Dòng 1: sử dụng
class Document
mà rapidjson đã cung cấp. - Dòng 2: Khởi tạo
size
để lưu trữ kích thước dữ liệu. - Dòng 4: lấy dữ liệu từ file JSON,
_fileName
lưu trữ tên file (đây là hàm mà Cocos2d-x cung cấp sẵn, có thể viết lại hàm này bằng cách đọc tập tin nhị phân để lấy dữ liệu và kích thước). - Dòng 5: sử dụng
Construct
để tạo chuỗi có kích thước chính xác với dữ liệu. - Dòng 7: sử dụng hàm
Parse
để lưu thông tin vào Document.
Sau bước này có m_document
với đầy đủ thông tin ở trên.
Cách sử dụng dữ liệu đã đọc từ JSON
Framework RapidJSON cung cấp 1 số hàm như sau:
Truy cập các phần tử
m_document["hello"]; m_document["keys"]["string"]; m_document["array"][0]; m_document["array"][1];
- Dòng 1: truy cập phần tử trên cùng, có tên là "
hello
". - Dòng 3: để truy cập tới "
string
" thì bắt buộc phải truy cập qua "keys
". - Dòng 5, 6: truy cập tới phần tử đầu tiên và thứ 2 trong mảng.
Xét kiểu dữ liệu của phần tử
Các hàm như sau:
IsString()
: trả vềtrue
nếu giá trị của nó làstring
, ngược lại thìfalse
IsNumber()
: trả vềtrue
nếu giá trị của nó là số, ngược lại thìfalse
IsObject()
: trả vềtrue
nếu giá trị của nó là 1 object, ngược lại thìfalse
IsArray()
: trả vềtrue
nếu giá trị của nó là 1 mảng dữ liệu, ngược lại thìfalse
IsBool()
: trả vềtrue
nếu giá trị của nó là 1 phép luận lý, ngược lại thìfalse
IsNull()
: trả vềtrue
nếu giá trị của nó lànull
, ngược lại thìfalse
- ...
Đây là 1 ví dụ minh họa:
m_document["hello"].IsString(); m_document["hello"].IsNumber(); m_document["i"].IsNumber(); m_document["hello"].IsObject(); m_document["keys"].IsObject();
Kết quả:
true false true false true
Lấy dữ liệu từ các phần tử
Các hàm như sau:
GetString()
: trả về giá trị là kiểu dữ liệustring
của phần tử đó.GetInt()
: trả về giá trị là kiểu dữ liệuint
của phần tử đó.GetDouble()
: trả về giá trị là kiểu dữ liệudouble
của phần tử đó.GetBool()
: trả về giá trị là kiểu dữ liệubool
của phần tử đó.- ...
Ví dụ minh họa:
string str = m_document["hello"].GetString(); bool variableT = m_document["t"].GetBool(); int variableI = m_document["i"].GetInt();
Xét xem có tồn tại phần tử
m_document.HasMember("keys"); m_document.HasMember("string"); m_documenet["keys"].HasMember("string");
Kết quả:
true false true
Hàm trả về true
nếu có phần tử, ngược lại thì false
.
- Dòng 3: Phải truy cập qua "
keys
" để xét, tương tự với việc truy cập.
Kiểu dữ liệu Value
Để tiện lợi trong việc sử dụng các thông tin.
rapidjson::Value& m_doc1 = m_document["hello"];
Cách sử dụng.
m_doc1.IsString(); // tương tự với m_document["hello"].IsString();
Truy cập tất cả phần tử trong mảng
Để truy cập vào tất cả phần tử trong mảng có 2 cách sau:
Cách 1
for (rapidjson::Value::ConstValueIterator itr = m_document["array"].Begin(); itr != m_document["array"].End(); ++itr) { itr->IsInt(); }
Cách 2
for (int i = 0; i < m_document["array"].Size(); ++i) { m_document["array"][i].IsInt(); }
Truy cập tất cả phần tử trong Object
for (rapidjson::Value::ConstMemberIterator itr = _document.MemberBegin(); itr != _document.MemberEnd(); ++itr) { itr->name.IsString(); itr->value.IsString(); }
- Truy cập tới các phần tử trong
Object
đó. - Truy cập tới giá trị của các phần tử đó.