Giả sử rằng nội dung của tệp Foo.txt
như sau.Làm cách nào để bỏ qua bộ nhớ cache của hệ thống tệp khi đọc tệp ở Golang?
Foo Bar Bar Foo
Hãy xem chương trình ngắn sau đây.
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)
}
Khi chúng tôi chạy chương trình trên, chúng tôi không gặp lỗi nào, đó là hành vi đúng.
Bây giờ, tôi sửa đổi dòng syscall.Open
thành các dòng sau.
fd, err := syscall.Open("Foo.txt", syscall.O_RDONLY | syscall.O_SYNC | syscall.O_DIRECT, 0)
Khi tôi chạy lại chương trình, tôi nhận được kết quả sau (không mong muốn).
Failed on read: invalid argument
Làm thế nào tôi có thể một cách chính xác thông qua các cờ syscall.O_SYNC
và syscall.O_DIRECT
theo quy định của các open
man page cho bỏ qua bộ nhớ cache hệ thống tập tin?
Lưu ý rằng tôi đang sử dụng giao diện syscall
tập tin trực tiếp thay vì giao diện os
tập tin bởi vì tôi không thể tìm thấy một cách để vượt qua những lá cờ vào các chức năng được cung cấp bởi os
, nhưng tôi mở cửa cho các giải pháp sử dụng os
với điều kiện chúng hoạt động chính xác để tắt bộ nhớ cache của hệ thống tệp trên lần đọc.
Cũng lưu ý rằng tôi đang chạy trên Ubuntu 14.04
với ext4
làm hệ thống tệp của tôi.
Cập nhật: Tôi cố gắng để sử dụng gói @Nick Craig-Wood trong các mã dưới đây.
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)
}
}
Đầu ra là sau
Error on read: unexpected EOF
Các bạn đã cố gắng làm mở đọc chặt chẽ với những chính xác đối số trong một cái gì đó khác hơn là đi (C có thể)? Từ những gì tôi có thể thấy trên trang người đàn ông, O_SYNC chỉ ảnh hưởng đến các hoạt động ghi và O_DIRECT cần một số loại bộ đệm có kích thước chính xác (?) Trong không gian người dùng, đây có thể là vấn đề cụ thể, nhưng trước tiên tôi cố gắng làm việc đó trong C ... – mrd0ll4r
@ mrd0ll4r, Thực ra tôi đã chạy [chương trình này] (http://man7.org/tlpi/code/online/book/filebuff/direct_read.c.html) và gặp lỗi tương tự 'EINVAL' trên phía C. Vì vậy, không, nó không đi cụ thể. – merlin2011