Предположим, что содержимое файла Foo.txt
выглядит следующим образом.Как пропустить кеш файловой системы при чтении файла в Golang?
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, err := syscall.Open("Foo.txt", syscall.O_RDONLY | syscall.O_SYNC | syscall.O_DIRECT, 0)
Когда я снова запускаю программу, я получаю следующий (нежелательный) вывод.
Failed on read: invalid argument
Как правильно передать флаги syscall.O_SYNC
и syscall.O_DIRECT
, как определено в open
man page для пропуска кэш файловой системы?
Обратите внимание, что я использую интерфейс syscall
файла непосредственно вместо интерфейса os
файла, потому что я не мог найти способ передать эти флаги в функцию, предоставляемой os
, но я открыт для решений, использующих os
при условии, что они работают правильно, чтобы отключить кеш файловой системы при чтении.
Обратите внимание, что я запускаю Ubuntu 14.04
с ext4
в качестве моей файловой системы.
Update: Я пытался использовать пакет @Nick Крэйга-Вуда в коде ниже.
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
Вы пытались сделать открытым для чтения рядом с теми, точным аргументы в чем-то еще, чем идти (возможно, C)? Из того, что я могу видеть на странице руководства, O_SYNC влияет только на операции записи, а O_DIRECT нуждается в каком-то буфере с точным размером (?) В пользовательском пространстве, это может быть проблемой, связанной с конкретным ходом, но я сначала попытаюсь получить эту работу в C ... – mrd0ll4r
@ mrd0ll4r, На самом деле я запустил [эту программу] (http://man7.org/tlpi/code/online/book/filebuff/direct_read.c.html) и получил ту же ошибку 'EINVAL' on сторона С. Нет, это не так. – merlin2011