在系統級編程與網絡通訊中,高效的輸入輸出流處理至關重要。本文深入剖析一套用 C 語言實現的輕量級 IO 流庫,涵蓋輸出流與輸入流的創建、數據讀寫、動態擴容、字節序控制以及內存管理機制。通過完整的頭文件與源碼解析,幫助開發者掌握流操作的核心原理與工程實踐。
庫定義了兩個核心結構體,分別對應輸出流與輸入流,均包含字節序標識、數據緩衝區指針,並各自維護位置、長度等狀態:
#define BASE_STREAM\
BYTE byte_order;\
BYTE* data;\
struct fs_input_stream {\
BASE_STREAM\
size_t pos;\
size_t len;\
fs_bool copy;\
fs_script_id script_id;\
};\
struct fs_output_stream {\
BASE_STREAM\
size_t pos;\
size_t buff_len;\
fs_script_id script_id;\
};
fs_create_output_stream 分配指定大小的緩衝區,初始化位置與長度;fs_stream_free_output 負責釋放緩衝區與結構體本身,防止內存洩漏。
所有具體類型的寫入函數(如 fs_stream_write_uint32、fs_stream_write_float 等)最終都調用 fs_stream_write_data。該函數實現自動擴容機制:當剩餘空間不足時,將緩衝區翻倍(buff_len << 1),確保寫入操作不會失敗。
void fs_stream_write_data(struct fs_output_stream* stream, BYTE* data, size_t len) {\
while (stream->pos + len > stream->buff_len) {\
void* new_data = fs_realloc(stream->data, stream->buff_len << 1);\
stream->data = (BYTE*)new_data;\
stream->buff_len <<= 1;\
}\
memcpy(stream->data + stream->pos, data, len);\
stream->pos += len;\
}
fs_stream_get_dataptr:返回緩衝區起始地址,供外部直接讀取。fs_stream_get_len:返回已寫入的有效數據長度。fs_stream_output_sub:將緩衝區中指定區間的數據移動到起始位置,並更新長度,實現「切片」功能。fs_create_input_stream:零拷貝模式,直接引用外部數據指針,適合只讀場景。fs_create_input_stream_with_copy:深拷貝模式,內部分配內存並複製數據,適合需要修改或延長生命週期的場景。fs_input_stream_set_data 與 fs_input_stream_set_data_copy 允許運行時切換數據源,並自動處理舊數據的釋放(僅在 copy 標誌為真時)。fs_input_stream_set_order 支持大小端切換,滿足跨平台通訊需求。
源碼中通過宏 _stream_read(TYPE) 統一實現各類型讀取:從當前位置拷貝指定大小的數據到局部變量,推進位置指針,返回值。這既減少代碼重複,又保證類型安全。
#define _stream_read(TYPE)\
TYPE v = 0;\
memcpy(&v, stream->data + stream->pos, sizeof(v));\
stream->pos += sizeof(v);\
return v;\
BYTE fs_stream_read_byte(struct fs_input_stream* stream) { _stream_read(BYTE); }\
uint32_t fs_stream_read_uint32(struct fs_input_stream* stream) { _stream_read(uint32_t); }\
// ... 其他類型同理
輸入/輸出流均提供 set_script_id / get_script_id 接口,允許將流與腳本標識綁定,便於在腳本虛擬機或多協議環境中追蹤流的來源與用途。
memcpy 實現類型無關的字節操作,避免嚴格別名規則問題。<string.h> 與自定義內存管理(fs_malloc/fs_free/fs_realloc),易於移植。這套 IO 流庫展示了 C 語言在資源受限環境下構建高性能、類型安全基礎設施的典範模式,適合嵌入式系統、遊戲網絡層、腳本虛擬機等場景集成使用。