fsync
文档状态
调用 fsync() 不一定确保包含该文件的目录中的条目也已到达磁盘。为此,还需要在目录的文件描述符上显式 fsync()。
我正在尝试使用 Windows 上的 SMB 将目录同步到网络映射驱动器,类似于fsync
Linux 上的操作。
如果目录存储在本地驱动器上,则以下 go 代码片段可以正常工作,但如果目录存储在网络映射文件夹上则失败。
func main() {
dir := "Z:\\smb-test" // Path to network mapped drive
f, err := openDir(dir)
if err != nil {
log.Fatal(err)
}
// Works fine if the path is located on a local disk but
// fails if the directory is on a network mapped drive
if err := f.Sync(); err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
func openDir(path string) (*os.File, error) {
fd, err := openDirWin(path)
if err != nil {
return nil, err
}
return os.NewFile(uintptr(fd), path), nil
}
func openDirWin(path string) (fd syscall.Handle, err error) {
pathp, err := syscall.UTF16PtrFromString(path)
if err != nil {
return syscall.InvalidHandle, err
}
access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE)
sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
createmode := uint32(syscall.OPEN_EXISTING)
fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0)
}
该程序失败
Z:\\smb-test Incorrect function.
MSDN 声明传入的句柄应该是文件句柄或卷的句柄,但没有提及目录。 https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-flushfilebuffers
并且 FlushFileBuffers 未列为接受目录句柄的函数 https://docs.microsoft.com/en-us/windows/desktop/fileio/obtaining-a-handle-to-a-directory
Invalid Device Request
我还注意到网络映射驱动器的 flushfilebuffers 系统调用失败
所以问题是如何在 Windows 上同步目录?还是窗口的缓冲 I/O 与 POSIX 根本不同,当目录中的文件被修改时我们不需要刷新目录?