我有一个GoLang软件包,使用os.OpenFile
和bufio.Reader
从fifo读取和写入。在Linux上,读者被告知作者已关闭该文件。然而,在达尔文它永远不会收到EOF。
package main
import (
"bufio"
"fmt"
"os"
"time"
)
// @note This is used to get around bufio.Scanner erroring at large lines
func readln(r *bufio.Reader) (string, error) {
var (
isPrefix = true
err error
line, ln []byte
)
for isPrefix && err == nil {
line, isPrefix, err = r.ReadLine()
ln = append(ln, line...)
}
return string(ln), err
}
func reader(filePath string) {
f, err := os.Open(filePath)
if err != nil {
panic(err)
}
reader := bufio.NewReader(f)
fmt.Print("READER >> created\n")
line, readErr := readln(reader)
for readErr == nil {
fmt.Printf("READER >> read 1 line: %+v\n", line)
line, readErr = readln(reader)
}
fmt.Printf("READER >> read finished: %+v\n", readErr)
}
func writer(filePath string) {
f, err := os.OpenFile(filePath, os.O_WRONLY, 0600)
fmt.Printf("WRITER << opened: %+v|%+v\n", f, err)
if err != nil {
panic(err)
}
fmt.Printf("WRITER << encoder created\n")
for i := 0; i < 3; i++ {
time.Sleep(1 * time.Second)
_, err = f.WriteString(fmt.Sprint("line", i, "\n"))
fmt.Printf("WRITER << written line%d, %+v\n", i, err)
}
time.Sleep(1 * time.Second)
err = f.Close()
fmt.Printf("WRITER << closed: %+v\n", err)
}
func main() {
fifo := os.Args[1]
fmt.Printf("STARTED %s\n", fifo)
go writer(fifo)
reader(fifo)
fmt.Print("ALL DONE\n")
}
Here is a repository再现了这种情况。
OSX
go version go1.10 darwin/amd64
STARTED /var/folders/k_/zdt3jb2j7gx1rnf379k_51gh0000gn/T/tmp.ksHGLSvs/fifo
READER >> created
WRITER << opened: &{file:0xc42009e000}|<nil>
WRITER << encoder created
WRITER << written line0, <nil>
READER >> read 1 line: line0
WRITER << written line1, <nil>
READER >> read 1 line: line1
WRITER << written line2, <nil>
READER >> read 1 line: line2
WRITER << closed: <nil>
^C
signal: interrupt
的Linux
go version go1.10 linux/amd64
STARTED /tmp/tmp.6if4ZSWnZ8/fifo
READER >> created
WRITER << opened: &{file:0xc42008c000}|<nil>
WRITER << encoder created
WRITER << written line0, <nil>
READER >> read 1 line: line0
WRITER << written line1, <nil>
READER >> read 1 line: line1
WRITER << written line2, <nil>
READER >> read 1 line: line2
WRITER << closed: <nil>
READER >> read finished: EOF
ALL DONE
这是向读者表明作者已完成的正确方法吗?