为什么f1.Read(buf)没有读出内容到buf?

问题描述 投票:0回答:3
package main

import (
    "fmt"
    "os"
    "io"
)

func main() {

    f1,_ := os.Create("f1")

    io.WriteString(f1, "some content")

    buf := make([]byte, 8)

    f1.Read(buf)

    fmt.Println(buf)

}

我创建一个文件,然后写入一些字符串。然后宣读,但没有内容。

输出是:

go run test.go
[0 0 0 0 0 0 0 0]
go
3个回答
1
投票

在Go中,不要忽略错误。写入和读取文件时,请跟踪当前文件偏移量。

写入后,偏移量位于文件结尾处,您需要在读取之前将偏移量设置为文件起始位置。例如,有了诊断信息,

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    f1, err := os.Create("f1")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f1.Close()
    // The file offset is its current location.
    s, err := f1.Seek(0, io.SeekCurrent)
    if err != nil {
        fmt.Println(s, err)
        return
    }
    fmt.Println("offset:", s)
    // writing takes place at the file offset, and
    // the file offset is incremented by the number of bytes actually
    // written.
    n, err := f1.WriteString("some content")
    fmt.Println("write: ", n, err)
    if err != nil {
        fmt.Println(n, err)
        return
    }
    // The file offset is its current location
    s, err = f1.Seek(0, io.SeekCurrent)
    if err != nil {
        fmt.Println(s, err)
        return
    }
    fmt.Println("offset:", s)

    buf := make([]byte, 8)

    // the read operation commences at the
    // file offset, and the file offset is incremented by the number of
    // bytes read.  If the file offset is at or past the end of file, no
    // bytes are read, and read() returns zero.
    n, err = f1.Read(buf[:cap(buf)])
    fmt.Println("read:  ", n, err)
    buf = buf[:n]
    fmt.Println("buffer:", len(buf), buf)
    if err != nil {
        if err != io.EOF {
            fmt.Println(n, err)
            return
        }
    }

    // The file offset is set to the start-of-file.
    s, err = f1.Seek(0, io.SeekStart)
    if err != nil {
        fmt.Println(s, err)
        return
    }
    fmt.Println("offset:", s)
    // the read operation commences at the
    // file offset, and the file offset is incremented by the number of
    // bytes read.  If the file offset is at or past the end of file, no
    // bytes are read, and read() returns zero.
    n, err = f1.Read(buf[:cap(buf)])
    fmt.Println("read:  ", n, err)
    buf = buf[:n]
    fmt.Println("buffer:", len(buf), buf)
    if err != nil {
        if err != io.EOF {
            fmt.Println(n, err)
            return
        }
    }
}

游乐场:https://play.golang.org/p/hPUn1ltKP2t

输出:

offset: 0
write:  12 <nil>
offset: 12
read:   0 EOF
buffer: 0 []
offset: 0
read:   8 <nil>
buffer: 8 [115 111 109 101 32 99 111 110]

1
投票

通常是因为写入的信息可能尚未刷新并存储到磁盘以供读取。尝试关闭文件并重新打开以进行阅读:

f1, _ := os.Create("/tmp/f1")

io.WriteString(f1, "some content")
f1.Close()

buf := make([]byte, 8)

f1, _ = os.Open("/tmp/f1")

f1.Read(buf)

fmt.Println(buf)

打印

[115 111 109 101 32 99 111 110]

有趣的是,如果您只是获得该文件的不同处理程序,它也会起作用。但是,我怀疑这可能非常不稳定,并且依赖于特定于操作系统的文件系统实现(在我的情况下是OSX APFS)。写入只是真正完成Close没有返回错误:

f1, _ := os.Create("/tmp/f1")

io.WriteString(f1, "some content")

buf := make([]byte, 8)

f2, _ := os.Open("/tmp/f1")

f2.Read(buf)

fmt.Println(buf)

打印:

[115 111 109 101 32 99 111 110]

更正:如下面的注释所示,将光标倒在同一个句柄上也应该有效:

f1, _ := os.Create("/tmp/f1")

io.WriteString(f1, "some content")

f1.Seek(0, 0)

buf := make([]byte, 8)

f1.Read(buf)

fmt.Println(buf)

打印:

[115 111 109 101 32 99 111 110]


-2
投票

写入文件后,使用Seek从文件的原点读取,该文件将从开始读取内容并插入到buf

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {

    f1, err := os.Create("f1")
    if err != nil {
        fmt.Println(err)
    }
    io.WriteString(f1, "some content")
    buf := make([]byte, 8)
    f1.Seek(0,0)
    n, err := f1.Read(buf)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(buf))
    fmt.Println(n)

}

输出:

一些内容12

© www.soinside.com 2019 - 2024. All rights reserved.