SDL3_API分类参考_输入输出流(CategoryIOStream)

2026-3-6 / 0 评论 / 9 阅读

输入输出流子系统(CategoryIOStream)

SDL 提供了一套用于读写数据流的抽象接口,支持文件、内存等多种数据源的实现,同时应用程序也可以自定义实现该接口。

注意SDL_IOStream 与 C++ 标准库中的 iostream 类无关联,仅二者都是用于读写数据的抽象接口这一点相似。


函数

  • SDL_CloseIO:关闭 IO 流(释放相关资源,关闭底层数据源)
  • SDL_FlushIO:刷新 IO 流(将缓冲区数据写入底层数据源,确保数据持久化)
  • SDL_GetIOProperties:获取 IO 流的属性(如是否可读写、是否支持定位等)
  • SDL_GetIOSize:获取 IO 流的总大小(字节),仅支持可定位的流
  • SDL_GetIOStatus:获取 IO 流的当前状态(成功、EOF、错误等)
  • SDL_IOFromConstMem:从只读内存块创建 IO 流(数据源为 const 内存,仅支持读操作)
  • SDL_IOFromDynamicMem:从动态内存创建 IO 流(自动管理内存,支持读写,可扩容)
  • SDL_IOFromFile:从文件创建 IO 流(指定文件路径和打开模式,如 "rb"、"wb" 等)
  • SDL_IOFromMem:从内存块创建 IO 流(数据源为可读写内存,支持读写操作)
  • SDL_IOprintf:格式化写入 IO 流(类似标准库 printf,输出到 IO 流)
  • SDL_IOvprintf:可变参数格式化写入 IO 流(底层实现,通常不直接调用)
  • SDL_LoadFile:加载整个文件到内存(自动分配内存,返回文件数据和大小)
  • SDL_LoadFile_IO:从 IO 流加载全部数据到内存(自动分配内存,适配任意 IO 流)
  • SDL_OpenIO:打开自定义 IO 流(基于 SDL_IOStreamInterface 实现自定义数据源)
  • SDL_ReadIO:从 IO 流读取指定字节数的数据到缓冲区(返回实际读取的字节数)
  • SDL_ReadS16BE:从 IO 流读取大端序 16 位有符号整数
  • SDL_ReadS16LE:从 IO 流读取小端序 16 位有符号整数
  • SDL_ReadS32BE:从 IO 流读取大端序 32 位有符号整数
  • SDL_ReadS32LE:从 IO 流读取小端序 32 位有符号整数
  • SDL_ReadS64BE:从 IO 流读取大端序 64 位有符号整数
  • SDL_ReadS64LE:从 IO 流读取小端序 64 位有符号整数
  • SDL_ReadS8:从 IO 流读取 8 位有符号整数(字节)
  • SDL_ReadU16BE:从 IO 流读取大端序 16 位无符号整数
  • SDL_ReadU16LE:从 IO 流读取小端序 16 位无符号整数
  • SDL_ReadU32BE:从 IO 流读取大端序 32 位无符号整数
  • SDL_ReadU32LE:从 IO 流读取小端序 32 位无符号整数
  • SDL_ReadU64BE:从 IO 流读取大端序 64 位无符号整数
  • SDL_ReadU64LE:从 IO 流读取小端序 64 位无符号整数
  • SDL_ReadU8:从 IO 流读取 8 位无符号整数(字节)
  • SDL_SaveFile:将内存数据保存到文件(指定路径和数据,自动创建/覆盖文件)
  • SDL_SaveFile_IO:将内存数据保存到 IO 流(适配任意可写 IO 流)
  • SDL_SeekIO:定位 IO 流的读写指针(支持相对当前位置、开头、末尾定位)
  • SDL_TellIO:获取 IO 流当前读写指针位置(距离流开头的字节数)
  • SDL_WriteIO:将缓冲区数据写入 IO 流(返回实际写入的字节数)
  • SDL_WriteS16BE:向 IO 流写入大端序 16 位有符号整数
  • SDL_WriteS16LE:向 IO 流写入小端序 16 位有符号整数
  • SDL_WriteS32BE:向 IO 流写入大端序 32 位有符号整数
  • SDL_WriteS32LE:向 IO 流写入小端序 32 位有符号整数
  • SDL_WriteS64BE:向 IO 流写入大端序 64 位有符号整数
  • SDL_WriteS64LE:向 IO 流写入小端序 64 位有符号整数
  • SDL_WriteS8:向 IO 流写入 8 位有符号整数(字节)
  • SDL_WriteU16BE:向 IO 流写入大端序 16 位无符号整数
  • SDL_WriteU16LE:向 IO 流写入小端序 16 位无符号整数
  • SDL_WriteU32BE:向 IO 流写入大端序 32 位无符号整数
  • SDL_WriteU32LE:向 IO 流写入小端序 32 位无符号整数
  • SDL_WriteU64BE:向 IO 流写入大端序 64 位无符号整数
  • SDL_WriteU64LE:向 IO 流写入小端序 64 位无符号整数
  • SDL_WriteU8:向 IO 流写入 8 位无符号整数(字节)

数据类型

  • SDL_IOStream:IO 流句柄类型(标识一个打开的 IO 流,所有操作均基于此句柄)

结构体

  • SDL_IOStreamInterface:IO 流接口结构体(自定义 IO 流时使用,包含读写、定位、关闭等函数指针)

枚举

  • SDL_IOStatus:IO 流状态枚举(成功、到达文件末尾、读错误、写错误、定位错误等)
  • SDL_IOWhence:IO 流定位基准枚举(SDL_IO_SEEK_SET:开头,SDL_IO_SEEK_CUR:当前位置,SDL_IO_SEEK_END:末尾)

  • (无)

FreeBASIC 示例代码

' 引入 SDL 相关声明(需确保 FreeBASIC 已链接 SDL3 库)
#Include "SDL.bi"

' 补充枚举/类型/函数声明(FreeBASIC 绑定可能缺失)
Enum SDL_IOWhence
    SDL_IO_SEEK_SET = 0  ' 相对于流开头
    SDL_IO_SEEK_CUR = 1  ' 相对于当前位置
    SDL_IO_SEEK_END = 2  ' 相对于流末尾
End Enum

Type SDL_IOStream As Any Ptr ' IO 流句柄

Declare Function SDL_IOFromFile CDecl (ByVal path As ZString Ptr, ByVal mode As ZString Ptr) As SDL_IOStream
Declare Function SDL_ReadIO CDecl (ByVal stream As SDL_IOStream, ByVal ptr As Any Ptr, ByVal size As UInteger, ByVal maxnum As UInteger) As UInteger
Declare Function SDL_WriteIO CDecl (ByVal stream As SDL_IOStream, ByVal ptr As Any Ptr, ByVal size As UInteger, ByVal num As UInteger) As UInteger
Declare Function SDL_SeekIO CDecl (ByVal stream As SDL_IOStream, ByVal offset As LongInt, ByVal whence As SDL_IOWhence) As LongInt
Declare Function SDL_TellIO CDecl (ByVal stream As SDL_IOStream) As LongInt
Declare Function SDL_GetIOSize CDecl (ByVal stream As SDL_IOStream) As LongInt
Declare Sub SDL_FlushIO CDecl (ByVal stream As SDL_IOStream)
Declare Sub SDL_CloseIO CDecl (ByVal stream As SDL_IOStream)
Declare Function SDL_IOprintf CDecl (ByVal stream As SDL_IOStream, ByVal fmt As ZString Ptr, ...) As Integer
Declare Function SDL_LoadFile CDecl (ByVal path As ZString Ptr, ByVal size As LongInt Ptr) As Any Ptr
Declare Sub SDL_free CDecl (ByVal ptr As Any Ptr)

' 补充大小端读写函数声明
Declare Function SDL_ReadU8 CDecl (ByVal stream As SDL_IOStream) As UByte
Declare Function SDL_ReadU16LE CDecl (ByVal stream As SDL_IOStream) As UShort
Declare Function SDL_ReadU32LE CDecl (ByVal stream As SDL_IOStream) As UInteger
Declare Function SDL_WriteU8 CDecl (ByVal stream As SDL_IOStream, ByVal value As UByte) As Integer
Declare Function SDL_WriteU16LE CDecl (ByVal stream As SDL_IOStream, ByVal value As UShort) As Integer
Declare Function SDL_WriteU32LE CDecl (ByVal stream As SDL_IOStream, ByVal value As UInteger) As Integer

' 示例1:文件 IO 流读写
Sub FileIOExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "【示例1:文件 IO 流读写】")

    ' 1. 创建/写入文件
    Dim As SDL_IOStream Ptr fileStream = SDL_IOFromFile(StrPtr("test_io.txt"), StrPtr("wb"))
    If (fileStream = NULL) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "打开文件失败:%s", SDL_GetError())
        Exit Sub
    End If

    ' 写入字符串
    Dim As ZString * 100 writeData = "SDL IOStream 测试数据"
    Dim As UInteger writeCount = SDL_WriteIO(fileStream, @writeData, 1, Len(writeData))
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "写入字节数:%u(预期:%u)", writeCount, Len(writeData))

    ' 格式化写入
    SDL_IOprintf(fileStream, StrPtr(vbCrLf & "数字:%d,浮点数:%.2f"), 123, 3.14)

    ' 刷新并关闭
    SDL_FlushIO(fileStream)
    SDL_CloseIO(fileStream)

    ' 2. 读取文件
    fileStream = SDL_IOFromFile(StrPtr("test_io.txt"), StrPtr("rb"))
    If (fileStream = NULL) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "打开文件失败:%s", SDL_GetError())
        Exit Sub
    End If

    ' 获取文件大小
    Dim As LongInt fileSize = SDL_GetIOSize(fileStream)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "文件大小:%lld 字节", fileSize)

    ' 分配缓冲区并读取全部内容
    Dim As Any Ptr readBuffer = SDL_malloc(fileSize + 1)
    If (readBuffer = NULL) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "内存分配失败")
        SDL_CloseIO(fileStream)
        Exit Sub
    End If

    Dim As UInteger readCount = SDL_ReadIO(fileStream, readBuffer, 1, fileSize)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "读取字节数:%u", readCount)

    ' 打印读取内容
    Dim As ZString Ptr readStr = Cast(ZString Ptr, readBuffer)
    readStr[readCount] = 0 ' 确保字符串终止
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "文件内容:%s", *readStr)

    ' 释放资源
    SDL_free(readBuffer)
    SDL_CloseIO(fileStream)
End Sub

' 示例2:内存 IO 流操作
Sub MemoryIOExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【示例2:内存 IO 流操作】")

    ' 1. 准备测试数据(小端序数值)
    Dim As UByte byteVal = &HFF
    Dim As UShort shortVal = &H1234
    Dim As UInteger intVal = &HABCD1234

    ' 2. 创建内存缓冲区并写入数据
    Dim As Byte Ptr memBuffer = Allocate(1024) ' 1KB 缓冲区
    Dim As SDL_IOStream Ptr memStream = SDL_IOFromMem(memBuffer, 1024)
    If (memStream = NULL) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "创建内存流失败:%s", SDL_GetError())
        Deallocate(memBuffer)
        Exit Sub
    End If

    ' 写入不同类型数据(小端序)
    SDL_WriteU8(memStream, byteVal)
    SDL_WriteU16LE(memStream, shortVal)
    SDL_WriteU32LE(memStream, intVal)

    ' 获取当前写入位置
    Dim As LongInt writePos = SDL_TellIO(memStream)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "写入后位置:%lld 字节", writePos)

    ' 3. 定位到流开头,读取数据
    SDL_SeekIO(memStream, 0, SDL_IO_SEEK_SET)

    Dim As UByte readByte = SDL_ReadU8(memStream)
    Dim As UShort readShort = SDL_ReadU16LE(memStream)
    Dim As UInteger readInt = SDL_ReadU32LE(memStream)

    ' 打印读取结果
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "读取数据:")
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  8位无符号整数:0x%02X(预期:0x%02X)", readByte, byteVal)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  16位无符号整数(小端):0x%04X(预期:0x%04X)", readShort, shortVal)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "  32位无符号整数(小端):0x%08X(预期:0x%08X)", readInt, intVal)

    ' 4. 关闭流并释放内存
    SDL_CloseIO(memStream)
    Deallocate(memBuffer)
End Sub

' 示例3:加载整个文件到内存
Sub LoadFileExample()
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "【示例3:加载整个文件到内存】")

    Dim As LongInt fileSize = 0
    Dim As Any Ptr fileData = SDL_LoadFile(StrPtr("test_io.txt"), @fileSize)

    If (fileData = NULL) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "加载文件失败:%s", SDL_GetError())
        Exit Sub
    End If

    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "加载文件大小:%lld 字节", fileSize)
    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "文件内容:%s", Cast(ZString Ptr, fileData))

    ' 释放 SDL_LoadFile 分配的内存
    SDL_free(fileData)
End Sub

' 主程序
Sub Main()
    ' 初始化 SDL
    If (SDL_Init(0) < 0) Then
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL 初始化失败:%s", SDL_GetError())
        Exit Sub
    End If

    ' 运行示例
    FileIOExample()
    MemoryIOExample()
    LoadFileExample()

    ' 清理 SDL
    SDL_Quit()

    SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, vbCrLf & "程序正常退出")
End Sub

' 运行主程序
Main()

核心知识点补充

  1. IO 流核心特性

    • 抽象性:统一的接口适配不同数据源(文件、内存、自定义流),切换数据源无需修改业务逻辑;
    • 定位支持:可通过 SDL_SeekIO/SDL_TellIO 实现随机读写,仅部分流(如文件、内存)支持定位;
    • 大小端适配:内置大端(BE)/小端(LE)数值读写函数,无需手动转换字节序,适配跨平台数据交换。
  2. IO 流打开模式规则

    • 与标准 C 库 fopen 模式兼容:
      • "r"/"rb":只读,文件不存在则失败;
      • "w"/"wb":只写,创建/覆盖文件;
      • "a"/"ab":追加,文件不存在则创建;
      • "r+"/"rb+":读写,文件不存在则失败;
    • 后缀 "b" 表示二进制模式,避免 Windows 平台的换行符转换。
  3. 读写函数返回值规则

    • SDL_ReadIO/SDL_WriteIO 的参数 size 是单个数据项的大小,maxnum/num 是数据项数量;
    • 返回值为实际读写的数据项数量(非字节数),例如:SDL_ReadIO(stream, buf, 4, 10) 尝试读取 10 个 4 字节整数,返回 5 表示读取了 5 个(20 字节);
    • 返回 0 可能表示到达流末尾(EOF)或操作失败,需通过 SDL_GetIOStatus 区分。
  4. 内存流类型差异

    • SDL_IOFromConstMem:只读内存流,数据源为 const 指针,不可写;
    • SDL_IOFromMem:可读写内存流,数据源为普通指针,大小固定;
    • SDL_IOFromDynamicMem:动态内存流,自动扩容,适合不确定数据大小的场景。

总结

  1. 核心优势

    • 统一抽象接口,适配多数据源,降低跨数据源切换成本;
    • 内置字节序转换函数,简化跨平台数据读写;
    • 提供 SDL_LoadFile/SDL_SaveFile 快捷函数,一键加载/保存文件;
    • 兼容标准 C 库文件操作模式,学习成本低。
  2. 使用建议

    • 优先使用 SDL_IOFromFile 处理文件读写,替代标准 C 库 fopen/fread/fwrite
    • 读写数值数据时,优先使用大小端专用函数(如 SDL_ReadU32LE),避免字节序错误;
    • 写入数据后调用 SDL_FlushIO 确保数据刷入底层存储,避免缓存丢失;
    • SDL_LoadFile 分配的内存必须用 SDL_free 释放,而非 free/Deallocate
  3. 关键接口

    • 流创建:SDL_IOFromFile()/SDL_IOFromMem()/SDL_IOFromDynamicMem()
    • 基础读写:SDL_ReadIO()/SDL_WriteIO()/SDL_IOprintf()
    • 定位操作:SDL_SeekIO()/SDL_TellIO()/SDL_GetIOSize()
    • 快捷操作:SDL_LoadFile()/SDL_SaveFile()
    • 资源管理:SDL_FlushIO()/SDL_CloseIO()

评论一下?

OωO
取消