typedef struct sqlite3_io_methods sqlite3_io_methods; struct sqlite3_io_methods { int iVersion; int (*xClose)(sqlite3_file*); int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); int (*xSync)(sqlite3_file*, int flags); int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); int (*xLock)(sqlite3_file*, int); int (*xUnlock)(sqlite3_file*, int); int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); int (*xFileControl)(sqlite3_file*, int op, void *pArg); int (*xSectorSize)(sqlite3_file*); int (*xDeviceCharacteristics)(sqlite3_file*); /* Methods above are valid for version 1 */ int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); void (*xShmBarrier)(sqlite3_file*); int (*xShmUnmap)(sqlite3_file*, int deleteFlag); /* Methods above are valid for version 2 */ int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); /* Methods above are valid for version 3 */ /* Additional methods may be added in future releases */ };
由 sqlite3_vfs.xOpen 方法打开的每个文件都会填充一个 sqlite3_file 对象(或更常见的是 sqlite3_file 对象的子类),其中包含指向此对象实例的指针。此对象定义用于对由 sqlite3_file 对象表示的打开文件执行各种操作的方法。
如果 sqlite3_vfs.xOpen 方法将 sqlite3_file.pMethods 元素设置为非 NULL 指针,则即使 sqlite3_vfs.xOpen 报告失败,也可能会调用 sqlite3_io_methods.xClose 方法。防止在 sqlite3_vfs.xOpen 失败后调用 xClose 的唯一方法是让 sqlite3_vfs.xOpen 将 sqlite3_file.pMethods 元素设置为 NULL。
xSync 的 flags 参数可以是 SQLITE_SYNC_NORMAL 或 SQLITE_SYNC_FULL 之一。第一个选项是正常的 fsync()。第二个选项是 Mac OS X 风格的 fullsync。可以将 SQLITE_SYNC_DATAONLY 标志与之进行 OR 操作,以指示只需要同步文件的数据,而不需要同步其 inode。
xLock() 和 xUnlock() 的整数值之一为
xFileControl() 方法是一个通用接口,允许自定义 VFS 实现使用 sqlite3_file_control() 接口直接控制打开的文件。第二个“op”参数是整数操作码。第三个参数是一个通用指针,用于指向可能包含参数或用于写入返回值的空间的结构。xFileControl() 的潜在用途可能是启用带超时的阻塞锁、更改锁定策略(例如使用点文件锁)、查询锁的状态或中断陈旧锁的功能。SQLite 内核保留所有小于 100 的操作码供自身使用。可以获得小于 100 的 操作码列表。定义自定义 xFileControl 方法的应用程序应使用大于 100 的操作码以避免冲突。VFS 实现应针对它们无法识别的文件控制操作码返回 SQLITE_NOTFOUND。
xSectorSize() 方法返回文件底层设备的扇区大小。扇区大小是可以在不干扰文件中的其他字节的情况下执行的最小写入操作。xDeviceCharacteristics() 方法返回一个描述底层设备行为的位向量
SQLITE_IOCAP_ATOMIC 属性表示任何大小的所有写入都是原子的。SQLITE_IOCAP_ATOMICnnn 值表示大小为 nnn 字节且对齐到为 nnn 的整数倍的地址的块的写入是原子的。SQLITE_IOCAP_SAFE_APPEND 值表示当将数据追加到文件时,首先追加数据,然后扩展文件大小,而不是反过来。SQLITE_IOCAP_SEQUENTIAL 属性表示信息以与对 xWrite() 的调用相同的顺序写入磁盘。
如果 xRead() 返回 SQLITE_IOERR_SHORT_READ,它还必须用零填充缓冲区的未读取部分。看似可以正常工作的 VFS 可能会失败,无法进行零填充短读取。但是,无法进行零填充短读取最终会导致数据库损坏。