Angenommen, der Inhalt der Datei Foo.txt
lautet wie folgt.Wie überspringe ich den Dateisystem-Cache beim Lesen einer Datei in Golang?
Foo Bar Bar Foo
Betrachten Sie das folgende kurze Programm.
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)
}
Wenn wir das Programm oben ausführen, erhalten wir keine Fehler, was das richtige Verhalten ist.
Jetzt ändere ich die syscall.Open
Zeile, um die folgenden zu sein.
fd, err := syscall.Open("Foo.txt", syscall.O_RDONLY | syscall.O_SYNC | syscall.O_DIRECT, 0)
Wenn ich das Programm erneut ausführen, bekomme ich folgende (unerwünschte) Ausgabe.
Failed on read: invalid argument
Wie kann ich die Flaggen korrekt passieren syscall.O_SYNC
und syscall.O_DIRECT
wie zum Überspringen der Dateisystem-Cache durch die der open
man page angegeben?
Bitte beachte, dass ich bin mit der syscall
File-Schnittstelle direkt anstelle des os
Datei-Schnittstelle, weil ich nicht einen Weg finden könnte durch os
diese Fahnen in die Funktionen zur Verfügung gestellt passieren, aber ich bin offen für Lösungen, die os
Lizenz verwendet werden, Sie funktionieren ordnungsgemäß, um den Dateisystemcache bei Lesevorgängen zu deaktivieren.
Beachten Sie auch, dass ich auf Ubuntu 14.04
mit ext4
als mein Dateisystem läuft.
aktualisieren: Ich habe versucht, unter @ Nick Craig-Wood-Paket im Code zu verwenden.
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)
}
}
Die Ausgabe ist die folgende
Error on read: unexpected EOF
Haben Sie versucht, die Open-Lese schließen mit denen genau zu tun Argumente in etwas anderes als gehen (C vielleicht)? Von dem, was ich auf der man-Seite sehen kann, betrifft O_SYNC nur Schreiboperationen und O_DIRECT benötigt einen genau bemessenen (?) Puffer im Benutzerbereich, dies könnte ein Go-spezifisches Problem sein, aber ich würde zuerst versuchen, das zu erreichen in C ... – mrd0ll4r
@ mrd0ll4r, Tatsächlich lief ich [dieses Programm] (http://man7.org/tlpi/code/online/book/filebuff/direct_read.c.html) und bekam den gleichen Fehler 'EINVAL' auf die C-Seite. Also nein, es ist nicht spezifisch. – merlin2011