加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 在Golang中读取文件时如何跳过文件系统缓存?

发布时间:2020-12-14 02:20:57 所属栏目:Linux 来源:网络整理
导读:假设文件Foo.txt的内容如下. Foo Bar Bar Foo 考虑以下简短程序. package mainimport "syscall"import "fmt"func main() { fd,err := syscall.Open("Foo.txt",syscall.O_RDONLY,0) if err != nil { fmt.Println("Failed on open: ",err) } data := make([]by
假设文件Foo.txt的内容如下.
Foo Bar Bar Foo

考虑以下简短程序.

package main

import "syscall"
import "fmt"


func main() {
    fd,err := syscall.Open("Foo.txt",syscall.O_RDONLY,0)
    if err != nil {
        fmt.Println("Failed on open: ",err)
    }
    data := make([]byte,100)
    _,err = syscall.Read(fd,data)
    if err != nil {
        fmt.Println("Failed on read: ",err)
    }
    syscall.Close(fd)
}

当我们运行上面的程序时,我们没有错误,这是正确的行为.

现在,我将syscall.Open行修改为以下内容.

fd,syscall.O_RDONLY | syscall.O_SYNC | syscall.O_DIRECT,0)

当我再次运行程序时,我得到以下(不合需要的)输出.

Failed on read:  invalid argument

如何正确传递open man page指定的标志syscall.O_SYNC和syscall.O_DIRECT以跳过文件系统缓存?

请注意,我直接使用syscall文件接口而不是os文件接口,因为我找不到将这些标志传递给os提供的函数的方法,但我对使用os的解决方案持开放态度,前提是它们正常??工作以禁用读取时的文件系统缓存.

另请注意,我在Ubuntu 14.04上运行,ext4作为我的文件系统.

更新:我尝试在下面的代码中使用@Nick Craig-Wood的软件包.

package main

import "io"
import "github.com/ncw/directio" 
import "os"
import "fmt"


func main() {
    in,err := directio.OpenFile("Foo.txt",os.O_RDONLY,0666)
    if err != nil {
        fmt.Println("Error on open: ",err)
    }

    block := directio.AlignedBlock(directio.BlockSize)
    _,err = io.ReadFull(in,block)
    if err != nil {
        fmt.Println("Error on read: ",err)
    }
}

输出如下

Error on read:  unexpected EOF

解决方法

您可能会喜欢我为此制作的 directio package.

来自网站

这是Go语言的库,可以在Go的所有支持的操作系统下使用Direct IO(openbsd和plan9除外).

直接IO在磁盘上执行IO,而不在OS中缓冲数据.当您正在阅读或编写大量您不想填充操作系统缓存的数据时,它非常有用.

请参阅此处了解包文档

http://go.pkgdoc.org/github.com/ncw/directio

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读