欢迎访问我的博客,你的支持,是我最大的动力!

Go语言学习笔记(8)-文件处理

Linux 小马奔腾 457℃ 评论
目录:
[显示]

文件处理

文件操作/数据处理
字符串、数字、JSON、XML等

文件操作

os 包中的文件操作函数:

func Mkdir(name string,perm FileMode) error 创建目录,名称为name权限为perm,如0777
func MkdirAll(path string,perm FileMode) error 创建多级子目录,mkdir -p
func Remove(name string) error 删除目录,当目录非空时会报错
func RemoveAll(path string) error 删除多级子目录,即便目录下有文件也会一并删除

创建文件与查看状态
func Create(name string)(file *File,err Error)
# 根据提供的文件名创建文件,返回文件对象,默认权限0666,返回的文件对象可读写
func NewFile(fd uintptr,name string) *File
# 根据文件描述符创建相应文件,返回文件对象
func MkdirAll(path string,perm FileMode) error
# 创建目录,若目录已存在不会执行操作,error值为nil表示创建成功
func Stat(name string)(FileInfo,error)
# 返回文件状态FileInfo对象

注意log.Fatal 打印完成后,会调用 os.Exit(1)

重命名和移动
func Rename(oldpath,newpath string) error
# 重命名和移动是同一个函数

打开与关闭

func Open(name string)(file *File,err Error)
# 以只读方式打开文件 内部调用的是 OpenFile()
func OpenFile(name string,flag int,perm uint32)(file *File,err Error)
# 其中flag是打开方式,包括只读、读写等;perm 是权限,如0666
# flag 中的属性可单独使用,也可组合使用,组合使用时可使用OR操作符,如
os.O_CREATE|os.O_APPEND
os.O_CREATE|os.O_TRUNC|os.O_WRONLY
属性说明:
os.O_RDONLY   //只读
os.O_WRONLY  //只写
os.O_RDWR      //读写
os.O_APPEND   //向文件中添加
os.O_CREATE    //若文件不存在则先创建
os.O_TRUNC     //文件打开时裁剪文件
os.O_EXCL        //和os.O_CREATE一起使用,文件不能存在
os.O_SYNC       //以同步IO方式打开
删除和截断
func Remove(name string)(err error)
# 删除文件
func Truncate(name string,size int)(err error)
# 截断文件 截断文件到size字节大小,或原始内容不足以null字节填充,传入0会清空文件

注意,使用Truncate时,若原始内容不足,以null填充后,会破坏文件格式

读写文件

1、复制文件

func io.Copy(dst Writer,src Reader)(written int64,err error)

注意,方件创建后需要关闭,使用io包 Copy() 后文件内容并不真正保存到文件 需要使用 Sync() 函数刷盘

2、跳转函数
跳转到文件指定位置,指定位置之后,可执行复制、剪切、粘贴等操作

func (f *File) Seek(offset int64,whence int)(ret int64,err error)

第一个参数是相对于第二个参数的偏移值
whence的值 :0-文件开始位置 1-当前位置 2-文件结尾

3、写入函数

func (file *File) Write(b []byte)(n int,err Error)
func (file *File) WriteAt(b []byte,off int64)(n int,err Error)  #在指定位置写入
func (file *File) WriteString(s string)(ret int,err Error) #写入string类型

权限控制

可修改文件权限,改变属主及时间戳,类似于 chmod chown 命令

func os.Chmod(name string,mode FileMode) error
func (f *File) Chmod(mode FileMode) error
func os.Chown(name string,uid,gid int) error
func (f *File) Chown(uid,gid int) error
func os.Chtimes(name string,atime time.Time,mtime time.Time) error

文件链接

软链接和硬链接,windows不支持 lchown

func os.Link(oldname, newname string) error  # 硬链接
func os.Symlink(oldname, newname string) error  # 软链接
func os.Lstat(name string)(FileInfo, error)  # 返回文件信息 当文件是软链接时 返回软链接信息 非引用的文件的信息
## os.Stat会获取软链接指向原文件信息
func os.Lchown(name string,uid,gid int) error  # 设置文件属主 当文件是软链接时 修改软链接本身属主

XML 处理
解析 XML

使用包 encoding/xml

func Unmarshal(data []byte, v interface{}) error

# data 是XML数据流;v 是要输出的结构,可以是任意格式(目前支持struct/slice/string),通常使用 struct解析XML

xml包内部通过反射进行数据映射,所以v里的字段必须是导出的
解析的优先级:先读取struct tag,再读取对应字段名(大小写敏感 必须完全匹配)
为正确解析,要求struct定义中所有字段必须是可导出的

解析XML到struct的规则:
1、若struct的一个字段是string或[]byte且tag含有",innerxml",解析时会将此字段对应的元素所有内嵌的原始XML累加到此字段上
2、若struct中有XMLName字段且类型为xml.Name,解析时会保存这个element的名字到该字段,如XMLName=servers
3、若struct中某字段tag定义含有XML结构中element的名称,解析时会把相应element赋值给该字段,如ServerName的解析
4、若struct中某字段tag定义中含有",attr",解析时会将该结构对应element的与字段同名的属性赋给该字段,如Version的解析
5、若struct中某字段tag定义形如"a>b>c",解析时会将XML结构a下面b下面c元素的赋给该字段
6、若struct中某字段tag定义了"-",解析时不会为该字段解析匹配任何XML数据
7、若struct中某字段tag定义了",any",解析时则它的子元素在不满足其他规则时就会匹配到这个字段
8、若struct中某字段tag包含",comments"且字段类型是[]byte或string,解析时XML中该元素包含的一条或多条注释内容会累加到该字段

生成 XML
func xml.Marshal(v interface{})([]byte,error)
func xml.MarshalIndent(v interface{},prefix,indent string)([]byte,error)   #会增加前缀和缩进,prefix前缀,indent缩进符

因为xml.MarshalIndent或xml.Marshal输出的是不带XML头的,所以需要使用xml.Header

xml包根据如下规则生成XML文件:v interface{}
1、若v是array或slice,输出每一个元素,类似value
2、若v是指针,输出指针指向的内容,若指针为空,什么都不输出
3、若v是interface,会处理interface所包含的数据
4、若v是其他数据类型,输出该数据类型拥有的字段信息

生成XML中element名字根据如下优先级从struct中获取:
1、若v是struct,取XMLName的tag中写义的名称
2、类型为xml.Name的名叫XMLName的字段的值
3、通过struct中字段的tag来获取
4、通过struct中字段名来获取
5、marshall的类型名称

设置struct中字段tag以控制最终XML生成:
1、tag中含有"-"的字段不会输出
2、tag中含有"name,attr",会以name作为属性名,字段值作为值输出该XML元素的属性,如version字段
3、tag中含有",attr",会以该struct字段名作为属性名输出XML元素的属性
4、tag中含有",chardata",输出为XML的character data而非element
5、tag中含有",innerxml",会原样输出,不进行常规的编码过程
6、tag中含有",comment",会被当作XML注释来输出,不进行常规的编码过程,字段值中不能含有"--"字符串
7、tag中含有"omitempty",若该字段的值为空值,该字段不会输出到XML,空值包括:false,0,nil、nil接口、长度为0的array/slice/map/string
8、tag中含有"a>b>c",会循环输出三个元素,a包含b,b包含c

JSON 处理
解析 JSON

一种是解析到结构体(知道json结构),一种是解析到接口(不清楚json结构)

func json.Unmarshal(data []byte,v interface{}) error

字段匹配规则:
注意,能被赋值的字段必须是可导出字段,找不到的字段会被忽略
1、首先查找tag中含有json中key的导出字段
2、其次查找字段名是json中key的导出字段
3、最后查找除首字母外其他大小写不敏感的导出字段(不区分大小写进行匹配)

json包中用 map[string]interface{} 和 []interface{} 结构来存储任意的JSON对象和数组
Go类型与JSON类型对应关系:
bool -> booleans
float64 -> numbers
string -> strings
nil -> null解析未知结构json可以使用simplejson
https://github.com/bitly/go-simplejson
go get -u github.com/bitly/go-simplejson

生成 JSON
func json.Marshal(v interface{})([]byte,error)

注意,输出JSON的字段名首字母都是大写
只有导出字段才会输出,要修改字段名称,需要定义 struct tag,如

定义 struct tag 规则:
1、字段tag为"-",该字段不会输出,如json:"-"
2、字段tag带有自定义名称,该自定义名称会出现在json字段名中
3、字段tag中包含"omitempty",若字段值为空,不会输出
4、若字段类型是bool,string,int,int64等,而tag中带有",string"选项,该字段在输出到json时会转换成json字符串

json.Marshal只在轮换成功时才会返回数据,转换中的注意点:
1、json对象只支持string作为key,所以要编码map,必须是map[string]T这种类型(T为任意类型)
2、channel、complex和function不能被编码成json
3、嵌套的数据是不能编码的,不然会让json编码进入死循环
4、指针在编码时会输出指针指向的内容,空指针会输出null

第三方库

根据已有json自动生成struct:https://github.com/ChimeraCoder/gojson
# curl -s https://api.github.com/repos/chimeracoder/gojson | gojson -name=Repository

获取json值:https://github.com/tidwall/gjson

日志记录

Go标准包中的log包只实现了简单的日志功能,不能保存到文件,没有复杂的功能

Logrus

logrus与标准log完全兼容且核心API很稳定,是go目前最活跃的日志库
https://github.com/sirupsen/logrus
go get -u github.com/sirupsen/logrus

Seelog

https://github.com/cihub/seelog
go get -u github.com/cihub/seelog
支持日志分配、过滤和格式化,可以使用XML的动态配置,支持热更新;支持多输出流,支持不同的日志输出,包括命令行、文件、缓存等;支持log rotate和smtp邮件提醒

压缩
打包

打包文件可以使用 archive/tar archive/zip 包

解包

压缩

使用 compress/bzip2 compress/flate compress/gzip compress/lzw compress/zlib 标准库

解压

 

转载请注明:轻风博客 » Go语言学习笔记(8)-文件处理

喜欢 (0)or分享 (0)