Golang 源码阅读 os.File

最近写程序过程感受golang读写文件比较慢。所以决定读一下源码。golang

src/os/file.gowindows

http://www.ieyebrain.com:8080/golang/src/os/file.goapp

中定义了file的函数:less

    Name, Read,Write,Seek,Close等等。函数

例如:Read函数ui

func (f *File) Read(b []byte) (n int, err error) {
    if f == nil {
        return 0, ErrInvalid
    }
    n, e := f.read(b)
    if n == 0 && len(b) > 0 && e == nil {
        return 0, io.EOF
    }
    if e != nil {
        err = &PathError{"read", f.name, e}
    }
    return n, err
}指针

这里实现了委托调用的接口技巧。就是把Read操做委托给f.read函数。f为File类型指针,找了一圈,才发现它定义在具体实现的文件中。好比:file_windows.go中,接口

http://www.ieyebrain.com:8080/golang/src/os/file_windows.goget

type File struct {
    *file
}
type file struct {
    fd      syscall.Handle
    name    string
    dirinfo *dirInfo   // nil unless directory being read
    l       sync.Mutex // used to implement windows pread/pwriteinput

    // only for console io
    isConsole bool
    lastbits  []byte // first few bytes of the last incomplete rune in last write
    readbuf   []rune // input console buffer
}

下面是读取的正主,syscall.Read(f.fd,b)。 File -> file -> syscall -> WindowsAPI

多了三次调用,File -> file是实现跨平台。 file 这一层加了一个锁。这个多是一个大的消耗。这个锁是为了统一的操做语义,在Unix平台上,并无这个锁。

func (f *File) read(b []byte) (n int, err error) {
    f.l.Lock()
    defer f.l.Unlock()
    if f.isConsole {
        return f.readConsole(b)
    }
    return fixCount(syscall.Read(f.fd, b))
}

调用过程:

1 http://www.ieyebrain.com:8080/golang/src/syscall/syscall_windows.go

func Read(fd Handle, p []byte) (n int, err error)  -> ReadFile

2 http://www.ieyebrain.com:8080/golang/src/syscall/zsyscall_windows.go

func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)

3 http://www.ieyebrain.com:8080/golang/src/runtime/syscall_windows.go

func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {     c := &getg().m.syscall     c.fn = fn     c.n = nargs     c.args = uintptr(noescape(unsafe.Pointer(&a1)))     cgocall(asmstdcallAddr, unsafe.Pointer(c))     return c.r1, c.r2, c.err }

相关文章
相关标签/搜索