博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang 源码阅读 os.File
阅读量:6816 次
发布时间:2019-06-26

本文共 1544 字,大约阅读时间需要 5 分钟。

hot3.png

最近写程序过程感觉golang读写文件比较慢。因此决定读一下源码。

src/os/file.go

中定义了file的函数:

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

例如:Read函数

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中,

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/pwrite

    // 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

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

2

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

3

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
}

 

 

 

 

转载于:https://my.oschina.net/u/612750/blog/787118

你可能感兴趣的文章
EXTJS在IE9下出现兼容性问题
查看>>
thinkphp5 多图片拖拽上传,自己写的,不足之处请指正~
查看>>
将Unicon字符串转成汉字String C#
查看>>
Centos 6.7 4TB 硬盘LVM 水平扩容
查看>>
maven 与多模块构建
查看>>
ubuntu14.04 配置tomcat8
查看>>
VirtualBox体验及介绍
查看>>
Ubuntu 12.04 下安装 JDK 7
查看>>
1>s.cpp(465) : error C2448: “main”: 函数样式初始值设定项类似函数定义 问题的解决方法...
查看>>
XWifiMouse早期写的一个Android鼠标App
查看>>
postgres预写式日志的内核实现详解-wal记录写入
查看>>
用面向接口编程思想看找对象
查看>>
OC文件操作习题
查看>>
Nginx常用命令
查看>>
TWaver GIS在电信中的使用
查看>>
几款程序员常用的辅助编程工具
查看>>
Python struct处理二进制
查看>>
FlashSwing教你如何布置组件
查看>>
字符串合并
查看>>
spring定时器配置
查看>>