应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

Go语言核心36讲(Go语言实战与应用二十二)学习笔记

  44使用os包中的API(上)
  我们今天要讲的是os代码包中的API。这个代码包可以让我们拥有操控计算机操作系统的能力。前导内容:os包中的API
  这个代码包提供的都是平台不相关的API。那么说,什么叫平台不相关的API呢?
  它的意思是:这些API基于(或者说抽象自)操作系统,为我们使用操作系统的功能提供高层次的支持,但是,它们并不依赖于具体的操作系统。
  不论是Linux、macOS、Windows,还是FreeBSD、OpenBSD、Plan9,os代码包都可以为之提供统一的使用接口。这使得我们可以用同样的方式,来操纵不同的操作系统,并得到相似的结果。
  os包中的API主要可以帮助我们使用操作系统中的文件系统、权限系统、环境变量、系统进程以及系统信号。
  其中,操纵文件系统的API最为丰富。我们不但可以利用这些API创建和删除文件以及目录,还可以获取到它们的各种信息、修改它们的内容、改变它们的访问权限,等等。
  说到这里,就不得不提及一个非常常用的数据类型:os。File。
  从字面上来看,os。File类型代表了操作系统中的文件。但实际上,它可以代表的远不止于此。或许你已经知道,对于类Unix的操作系统(包括Linux、macOS、FreeBSD等),其中的一切都可以被看做是文件。
  除了文本文件、二进制文件、压缩文件、目录这些常见的形式之外,还有符号链接、各种物理设备(包括内置或外接的面向块或者字符的设备)、命名管道,以及套接字(也就是socket),等等。
  因此,可以说,我们能够利用os。File类型操纵的东西太多了。不过,为了聚焦于os。File本身,同时也为了让本文讲述的内容更加通用,我们在这里主要把os。File类型应用于常规的文件。
  下面这个问题,就是以os。File类型代表的最基本内容入手。我们今天的问题是:os。File类型都实现了哪些io包中的接口?
  这道题的典型回答是这样的。
  os。File类型拥有的都是指针方法,所以除了空接口之外,它本身没有实现任何接口。而它的指针类型则实现了很多io代码包中的接口。
  首先,对于io包中最核心的3个简单接口io。Reader、io。Writer和io。Closer,os。File类型都实现了它们。
  其次,该类型还实现了另外的3个简单接口,即:io。ReaderAt、io。Seeker和io。WriterAt。
  正是因为os。File类型实现了这些简单接口,所以它也顺便实现了io包的9个扩展接口中的7个。
  然而,由于它并没有实现简单接口io。ByteReader和io。RuneReader,所以它没有实现分别作为这两者的扩展接口的io。ByteScanner和io。RuneScanner。
  总之,os。File类型及其指针类型的值,不但可以通过各种方式读取和写入某个文件中的内容,还可以寻找并设定下一次读取或写入时的起始索引位置,另外还可以随时对文件进行关闭。
  但是,它们并不能专门地读取文件中的下一个字节,或者下一个Unicode字符,也不能进行任何的读回退操作。
  不过,单独读取下一个字节或字符的功能也可以通过其他方式来实现,比如,调用它的Read方法并传入适当的参数值就可以做到这一点。问题解析
  这个问题其实在间接地问os。File类型能够以何种方式操作文件?我在前面的典型回答中也给出了简要的答案。
  在我进一步地说明一些细节之前,我们先来看看,怎样才能获得一个os。File类型的指针值(以下简称File值)。
  在os包中,有这样几个函数,即:Create、NewFile、Open和OpenFile。
  os。Create函数用于根据给定的路径创建一个新的文件。它会返回一个File值和一个错误值。我们可以在该函数返回的File值之上,对相应的文件进行读操作和写操作。
  不但如此,我们使用这个函数创建的文件,对于操作系统中的所有用户来说,都是可以读和写的。
  换句话说,一旦这样的文件被创建出来,任何能够登录其所属的操作系统的用户,都可以在任意时刻读取该文件中的内容,或者向该文件写入内容。
  注意,如果在我们给予os。Create函数的路径之上,已经存在了一个文件,那么该函数会先清空现有文件中的全部内容,然后再把它作为第一个结果值返回。
  另外,os。Create函数是有可能返回非nil的错误值的。比如,如果我们给定的路径上的某一级父目录并不存在,那么该函数就会返回一个os。PathError类型的错误值,以表示不存在的文件或目录。
  再来看os。NewFile函数。该函数在被调用的时候,需要接受一个代表文件描述符的、uintptr类型的值,以及一个用于表示文件名的字符串值。
  如果我们给定的文件描述符并不是有效的,那么这个函数将会返回nil,否则,它将会返回一个代表了相应文件的File值。
  注意,不要被这个函数的名称误导了,它的功能并不是创建一个新的文件,而是依据一个已经存在的文件的描述符,来新建一个包装了该文件的File值。
  例如,我们可以像这样拿到一个包装了标准错误输出的File值:file3:os。NewFile(uintptr(syscall。Stderr),devstderr)
  然后,通过这个File值向标准错误输出上写入一些内容:iffile3!nil{deferfile3。Close()file3。WriteString(TheGolanguageprogramwritesthecontentsintostderr。)}
  os。Open函数会打开一个文件并返回包装了该文件的File值。然而,该函数只能以只读模式打开文件。换句话说,我们只能从该函数返回的File值中读取内容,而不能向它写入任何内容。
  如果我们调用了这个File值的任何一个写入方法,那么都将会得到一个表示了坏的文件描述符的错误值。实际上,我们刚刚说的只读模式,正是应用在File值所持有的文件描述符之上的。
  所谓的文件描述符,是由通常很小的非负整数代表的。它一般会由IO相关的系统调用返回,并作为某个文件的一个标识存在。
  从操作系统的层面看,针对任何文件的IO操作都需要用到这个文件描述符。只不过,Go语言中的一些数据类型,为我们隐匿掉了这个描述符,如此一来我们就无需时刻关注和辨别它了(就像os。File类型这样)。
  实际上,我们在调用前文所述的os。Create函数、os。Open函数以及将会提到的os。OpenFile函数的时候,它们都会执行同一个系统调用,并且在成功之后得到这样一个文件描述符。这个文件描述符将会被储存在它们返回的File值中。
  os。File类型有一个指针方法,名叫Fd。它在被调用之后将会返回一个uintptr类型的值。这个值就代表了当前的File值所持有的那个文件描述符。
  不过,在os包中,除了NewFile函数需要用到它,它也没有什么别的用武之地了。所以,如果你操作的只是常规的文件或者目录,那么就无需特别地在意它了。
  最后,再说一下os。OpenFile函数。这个函数其实是os。Create函数和os。Open函数的底层支持,它最为灵活。
  这个函数有3个参数,分别名为name、flag和perm。其中的name指代的就是文件的路径。而flag参数指的则是需要施加在文件描述符之上的模式,我在前面提到的只读模式就是这里的一个可选项。
  在Go语言中,这个只读模式由常量os。ORDONLY代表,它是int类型的。当然了,这里除了只读模式之外,还有几个别的模式可选,我们稍后再细说。
  os。OpenFile函数的参数perm代表的也是模式,它的类型是os。FileMode,此类型是一个基于uint32类型的再定义类型。
  为了加以区别,我们把参数flag指代的模式叫做操作模式,而把参数perm指代的模式叫做权限模式。可以这么说,操作模式限定了操作文件的方式,而权限模式则可以控制文件的访问权限。关于权限模式的更多细节我们将在后面讨论。
  (获得os。File类型的指针值的几种方式)
  到这里,你需要记住的是,通过os。File类型的值,我们不但可以对文件进行读取、写入、关闭等操作,还可以设定下一次读取或写入时的起始索引位置。
  此外,os包中还有用于创建全新文件的Create函数,用于包装现存文件的NewFile函数,以及可被用来打开已存在的文件的Open函数和OpenFile函数。packagemainimport(bytesfmtioospathfilepathreflectsyscall)ioTypes代表了io代码包中的所有接口的反射类型。varioTypes〔〕reflect。Type{reflect。TypeOf((io。Reader)(nil))。Elem(),reflect。TypeOf((io。Writer)(nil))。Elem(),reflect。TypeOf((io。Closer)(nil))。Elem(),reflect。TypeOf((io。ByteReader)(nil))。Elem(),reflect。TypeOf((io。RuneReader)(nil))。Elem(),reflect。TypeOf((io。ReaderAt)(nil))。Elem(),reflect。TypeOf((io。Seeker)(nil))。Elem(),reflect。TypeOf((io。WriterTo)(nil))。Elem(),reflect。TypeOf((io。ByteWriter)(nil))。Elem(),reflect。TypeOf((io。WriterAt)(nil))。Elem(),reflect。TypeOf((io。ReaderFrom)(nil))。Elem(),reflect。TypeOf((io。ByteScanner)(nil))。Elem(),reflect。TypeOf((io。RuneScanner)(nil))。Elem(),reflect。TypeOf((io。ReadSeeker)(nil))。Elem(),reflect。TypeOf((io。ReadCloser)(nil))。Elem(),reflect。TypeOf((io。WriteCloser)(nil))。Elem(),reflect。TypeOf((io。WriteSeeker)(nil))。Elem(),reflect。TypeOf((io。ReadWriter)(nil))。Elem(),reflect。TypeOf((io。ReadWriteSeeker)(nil))。Elem(),reflect。TypeOf((io。ReadWriteCloser)(nil))。Elem(),}funcmain(){示例1。file1:(os。File)(nil)fileType:reflect。TypeOf(file1)varbufbytes。Bufferfmt。Fprintf(buf,TypeTimplements,file1)for,t:rangeioTypes{iffileType。Implements(t){buf。WriteString(t。String())buf。WriteByte(,)buf。WriteByte()}}output:buf。Bytes()output〔len(output)2〕。fmt。Printf(s,output)示例2。fileName1:something1。txtfilePath1:filepath。Join(os。TempDir(),fileName1)varpaths〔〕stringpathsappend(paths,filePath1)dir,:os。Getwd()pathsappend(paths,filepath。Join(dir〔:len(dir)1〕,fileName1))for,path:rangepaths{fmt。Printf(Createafilewithpaths。。。,path),err:os。Create(path)iferr!nil{varunderlyingErrstringif,ok:err。(os。PathError);ok{underlyingErr(patherror)}fmt。Printf(error:vs,err,underlyingErr)continue}fmt。Println(Thefilehasbeencreated。)}fmt。Println()示例3。fmt。Println(Newafileassociatedwithstderr。。。)file3:os。NewFile(uintptr(syscall。Stderr),devstderr)iffile3!nil{file3。WriteString(TheGolanguageprogramwritessomethingtostderr。)}fmt。Println()示例4。fmt。Printf(Openafilewithpaths。。。,filePath1)file4,err:os。Open(filePath1)iferr!nil{fmt。Printf(error:v,err)return}fmt。Println(Writesomethingtothefile。。。),errfile4。WriteString(something)varunderlyingErrstringif,ok:err。(os。PathError);ok{underlyingErr(patherror)}fmt。Printf(error:vs,err,underlyingErr)fmt。Println()示例5。fmt。Printf(Openafilewithpaths。。。,filePath1)file5a,err:os。Open(filePath1)iferr!nil{fmt。Printf(error:v,err)return}fmt。Printf(Isthereonlyonefiledescriptorforthesamefileinthesameprocess?v,file5a。Fd()file4。Fd())file5b:os。NewFile(file5a。Fd(),filePath1)fmt。Printf(Canthesamefiledescriptorrepresentthesamefile?v,file5b。Name()file5a。Name())fmt。Println()示例6。fmt。Printf(Reuseafileonpaths。。。,filePath1)file6,err:os。OpenFile(filePath1,os。OWRONLYos。OTRUNC,0666)iferr!nil{fmt。Printf(error:v,err)return}contents:somethingfmt。Printf(Writeqtothefile。。。,contents)n,err:file6。WriteString(contents)iferr!nil{fmt。Printf(error:v,err)}else{fmt。Printf(Thenumberofbyteswrittenisd。,n)}}总结
  我们今天讲的是os代码包以及其中的程序实体。我们首先讨论了os包存在的意义,和它的主要用途。代码包中所包含的API,都是对操作系统的某方面功能的高层次抽象,这使得我们可以通过它以统一的方式,操纵不同的操作系统,并得到相似的结果。
  在这个代码包中,操纵文件系统的API最为丰富,最有代表性的就是数据类型os。File。os。File类型不但可以代表操作系统中的文件,还可以代表很多其他的东西。尤其是在类Unix的操作系统中,它几乎可以代表一切可以操纵的软件和硬件。笔记源码
  https:github。comMingsonZhenggocoredemo

C罗让球王的门槛变得太高,梅西也只能勉强称王想要成为球王,必须有足够实力证明自己。贝利马拉多纳时代没有那么多奖项设置,但是到了现在足球环境已经很成熟,拿不到重大奖项,绝对称不上球王。综合能力评分,C罗650分,梅西……承诺2小时内解决客诉沪上直播电商抢抓38大促中国青年报客户端讯(中青报中青网记者张均斌)2月27日,在38大促前夕,直播电商行业企业美腕(上海)网络科技有限公司发布旗下李佳琦直播间所有女生直播间所有女生的衣橱等直播矩阵的……渐入佳境!巴黎拜仁各自30赢下联赛关键一役,静候欧冠生死战巴黎这边,客场挑战联赛积分榜第二的马赛。在这场备受瞩目的法国国家德比中,梅西打进1球并送出2次助攻,姆巴佩则贡献了2粒进球和1次助攻,两位巨星合力帮助巴黎以30战胜了对手,报了……国足新帅宣布上场规定,艾克森等两大悍将悬了!刚刚成为国足新主帅的扬科维奇,虽然教练成绩并不突出,但却对中国队队员提出了一个严格的要求:体脂率超过10的队员不能上场比赛!作为一名体育教练,控制运动员的体脂率是很正常的……兴凯湖畔女民警中俄边境冰凌花在祖国的东北边陲密山中俄边境,有这样两个身穿藏蓝警服的女孩,迎风冒雪,不畏严寒,巡逻辖区,以女性独有的细心、耐心坚守在边境一线,被称为中俄边境的冰凌花。她俩,就是鸡西市公安局兴……左手佛,右手情最后一片净土26可怜的农奴,放牧为主月作裳,打工活命地当床。贵族的孩子一出生就是高高在上的上等人,而农奴的孩子从来到这个世界上的那一秒,就继承了上几代人的高利贷,除此之外,还有非借不可的……中银策略兔年十大猜想核心结论节后A股在内外利好共振下将迎来估值修复行情。观点回顾01兔年十大猜想猜想一:中国经济引领全球,世界经济次第复苏。库存短周期,中国已进入被动去库,……哈尔滨中央大街有了新地标农投金谷大厦冰屋美食集市引游客竞相打来源:【人民网】人民网哈尔滨2月1日电(尚城)在百年老街哈尔滨中央大街上,路过金谷大厦的游客总会忍不住停下脚步,这里的一层门廊全部由冰砖搭建而成,晶莹剔透的冰屋已经成为哈……OpenWrt旁路由进阶SmartDNSAdGH设置DNS分本内容来源于什么值得买APP,观点仅代表作者本人作者:纵笔浮生写在前面1。iKuaiOpenWRT做旁路由网络拓扑前面几篇文章写完了,基本上折腾完了,以ESXi8。……刚刚,银保监会批复同意这家公司破产中国基金报泰勒刚刚,银保监会发布:原则同意北大方正集团财务有限公司进入破产程序。中国银保监会关于北大方正集团财务有限公司破产的批复北大方正集团财务有限公司:……10,000枚比特币被提走!SEC称是加密货币逃犯DoKwo美国证券交易委员会指控Kwon和他共同创办的公司在TerraUSD问题上有欺诈行为机构称10,000个比特币从Terra生态系统中转移出来Kwon开发了TerraU……HUAWEIMate60最新配置流出,全曲面屏太豪横了众所周知,华为曾凭借着麒麟芯片和鸿蒙系统这两大优势,干翻过三星和苹果,做到全球第一。但自从受到不公平遭遇之后,华为市场份额占比就不断下滑,令无数花粉都惋惜不已。近两年来,……
5000毫安4nm,国产高配旗舰再次发力,1T机身真的香吗中兴在现在的手机市场上可以说是减轻了很多压力了,在市场上也能算是轻装上阵了,并且最近对于中兴来说,市场的热度表现情况也是非常的好的,借着这个热度啊,中兴也是开始预热自己的下一款……上午10点,CBA伤情名单更新,杜锋折损3员大将,杨鸣机会来4月2日消息,本赛季cba季后赛已经在南昌火热打响,昨天进行的一场关键比赛中,广东队轻取天津队迎来开门红!说实话这个结果多少有些出乎意料,广东队本赛季内忧外患实力大幅下滑,常规……又一前男篮国手转投湾区翼龙,CBA慌了吗?此前效力于北京首钢男篮的刘晓宇,选择湾区翼龙作为自己职业生涯的下一站。据媒体报道,这名前中国男篮控卫日前已经与湾区翼龙完成签约,双方签下的是一份为期一年的合同。在搞定刘晓……洛阳四千金今日上线!看赖雨濛掌柜嫁到重振家道5月11日,由领誉传媒、腾讯视频共同出品,吴承峰导演,王大力编剧,赖雨濛、虞祎杰、高容方、卜祉亦、郑丞丞等领衔主演的古装轻喜微短剧《洛阳四千金》在腾讯视频正式上线。《洛阳……卷入裁员漩涡的大厂游戏人半年三次项目解散,薪资已经腰斩本文来源:时代财经作者:谢斯临图片来源:Pexel今年以来,游戏人的日子普遍都不太好过。从2021年年底开始,无论是互联网大厂,还是行业头部,几乎所有公司游戏……韩媒点评武磊返回中超1年进2个球,他只能灰头土脸回去北京时间8月11日,上海海港官宣武磊重返球队。随后,韩国媒体也对武磊重返中超进行报道了。韩国媒体表示,武磊在刚刚过去的202021赛季只打进了2个球,这样的表现让其无法在西班牙……鲫鱼汤这样做太赞了,包你吃不到一根鱼刺,汤白如牛奶鲜香无腥味鲫鱼汤很多人都爱喝,尤其是在天气炎热的夏天,当我们胃口不好的时候,能来上一碗鲫鱼汤,别提有多开胃了。像我就特别喜欢用鲫鱼汤来泡饭吃,要不就是用来下面吃,味道都是一绝。做得……中国女排3比0横扫波兰,首局25比8打蒙对手,世联赛战绩为6北京时间6月30日消息,2022年世界女排联赛第三周赛事继续进行,中国女排首局打出25比8的悬殊比分,最终以3比0战胜波兰女排,终结三连败。算上前两周,中国女排目前的战绩为6胜……雷军含泪甩卖旗舰跌至2829元小米11Pro某多多百亿补贴中,顶配版12256GB已从5699跌至2829元。在这个价位上,小米11Pro除了饱受诟病的骁龙888外其他配置都是十分不错的。尺寸1……钱小佳将张大大打哭!喜提双热搜第一!二人下场开喷玩不起?10号凌晨,咱们报道了钱小佳两分钟KO张大大一事。比赛打响后,在钱小佳接连的组合拳下,张大大很快招架不住,频频倒地的他突然激动起来,在现场大喊:他打我后脑勺!裁判不公平,换裁判……他的歌火遍大江南北,却在正火时隐退,刀郎说这是我自己的选择乐坛的新人旧人更替很快,但是却从来不缺少有才华的人。对于那些真正有才华的音乐人,即使他已经消失在了大众的视野中,但是他仍能成就一个乐坛传说,而这个人便是刀郎。刀郎虽然已经退居幕……传家看了这么久才明白易家人阿媛是什么意思,这么安排身份绝了《传家》是王威、白云默联合执导,由秦岚、韩庚、吴谨言、聂远、张楠、刘钧、苗圃、张逸杰等演员共同主演的电视剧。该剧以那个动荡年代为背景,讲述了易家三姐妹历经成长与抉择,齐心……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网