Windows OpenFile标志

时间:2018-11-01 23:50:09

标签: windows go

我正在尝试编写一个程序,该程序在允许其他应用程序访问文件的同时读取文件。我了解到,在Windows中,您需要传递syscall.FILESHARE_READ / WRITE标志以防止文件锁定。但是,引入这些标志会限制我从头开始读取文件,但会出现错误-读取“文件”:拒绝访问。 这是我的代码:

os.OpenFile(path, syscall.O_RDONLY | syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_READ, 0444)

我使用正确的标志吗? Windows是否允许此功能?

这是一个示例Go程序 使用此命令构建-      GOOS = windows GOARCH = amd64 go build -v -o testRead.exe

package main

import (
    "fmt"
    "os"
    "time"
    "bufio"
    "syscall"
)

func main() {

if len(os.Args) != 2 {
    fmt.Println("Specify file!")
    return
}

path := os.Args[1]
f, err := os.OpenFile(path, syscall.O_RDONLY|syscall.FILE_SHARE_WRITE | syscall.FILE_SHARE_READ, 0444)
//f, err := os.Open(path)
if err != nil {
    fmt.Println("Can't open file")
    fmt.Println(err)
    return
}
defer f.Close()

reader := bufio.NewReader(f)
line, _, err := reader.ReadLine()
if (err != nil) {
    fmt.Println(err)
}
fmt.Println(line)


// Keeps the program alive
t1 := time.Now().Local().Add(time.Second * time.Duration(3))
for {
    if time.Now().After(t1) {
        fmt.Println("Still Alive!")
        t1 = time.Now().Local().Add(time.Second * time.Duration(3))
    }
}
} 

我注意到os.Open和os.OpenFile(path,syscall.O_RDONLY,0444)可以正常读取。

1 个答案:

答案 0 :(得分:2)

XY问题是在询问您尝试的解决方案,而不是实际问题:The XY Problem


如果我们使用打开文件

f, err := os.OpenFile(path, syscall.O_RDONLY, 0444)

您的程序运行没有错误。

在Windows上,程序使用CreateFile

DesiredAccess = GENERIC_READ
ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE

由于某些未知原因,您在Windows上使用了任意os.OpenFile flag位粉碎。

f, err := os.OpenFile(path, syscall.O_RDONLY|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_READ, 0444)

其中

const (
    O_RDONLY   = 0x00000
    O_WRONLY   = 0x00001
    O_RDWR     = 0x00002

    FILE_SHARE_READ     = 0x00000001
    FILE_SHARE_WRITE    = 0x00000002
)

用不相关的文件共享位来粉碎os.OpenFile flag模式位,您已经

flag = syscall.O_RDONLY|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_READ

flag = O_RDONLY|O_WRONLY|O_RDWR

结果不确定。

在Windows上,报告错误:read test.file: Access is denied.

在Linux上,检测到错误:read test.file: bad file descriptor