Windows系统下创建/删除文件后是否需刷新目录以保证持久化?
Windows中CreateFile与DeleteFile的目录修改持久化问题
背景:Linux下的目录持久化逻辑
在Linux系统中,执行以下文件操作后,目录的修改不会自动同步到磁盘,函数会在目录变更落盘前就返回:
- 创建新文件:
creat(path,..)、open(new_path,O_CREAT..) - 删除文件:
unlink(path) - 重命名文件:
rename(src_path,dst_path)
若不手动处理目录持久化,断电或创建卷快照时,目录可能无法显示最新的文件变更。解决方法是先通过open(path_to_parent_dir)获取父目录的文件描述符,再调用fsync(..),最后close(..)强制目录修改落盘。
Windows下的对应疑问
Windows中调用MoveFileExA(src_path,dst_path,flags)时,可传入MOVEFILE_WRITE_THROUGH标志强制重命名操作的目录修改持久化,这说明Windows同样存在目录变更不自动落盘的问题。
那么对于以下两类操作,是否需要额外处理来确保目录修改持久化?
- 创建文件:使用带
CREATE_NEW/CREATE_ALWAYS参数的CreateFile(path,...) - 删除文件:
DeleteFile(path)
解答
1. 默认行为说明
CreateFile(创建文件场景)和DeleteFile不会在返回前确保目标目录的修改持久化到磁盘。它们仅保证文件本身的操作(创建文件内容/删除文件实体)完成,但父目录的元数据变更(新增/移除文件名到文件的映射)会被文件系统缓存,不会立即写入磁盘。
2. 手动持久化的实现方法
你给出的代码思路是正确的,需要打开目标文件的父目录,调用FlushFileBuffers强制目录元数据落盘,示例代码如下:
const auto dir_handle = CreateFile( path_to_parent_dir, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, // 必须指定此标志才能打开目录句柄 nullptr ); if (dir_handle != INVALID_HANDLE_VALUE) { FlushFileBuffers(dir_handle); CloseHandle(dir_handle); }
注意事项:
- 打开目录时必须传入
FILE_FLAG_BACKUP_SEMANTICS标志,否则CreateFile无法成功打开目录 - 务必检查
CreateFile的返回值,避免后续操作无效句柄
内容的提问来源于stack exchange,提问作者qbolec
相关产品推荐
相关产品推荐

