《Go语言从入门到精通》Go语言文件处理_第1页
《Go语言从入门到精通》Go语言文件处理_第2页
《Go语言从入门到精通》Go语言文件处理_第3页
《Go语言从入门到精通》Go语言文件处理_第4页
《Go语言从入门到精通》Go语言文件处理_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Go语言文件处理Go语言从入门到精通掌握Go语言中基本的文件操作了解二进制文件的有关知识01FILE02TEXT03BINARYtarget目标掌握文本文件相关的各种处理目录导航9.1Go语言中文本文件的处理Contents文件的基本知识

什么是文件(acomputerresourceforrecordingdatainastoragedevice)

文件名与文件的扩展名(扩展名的意义)

纯文本文件(*.txt)

图像文件(*.jpg,*.png,*.gif)

二进制文件(广义上,所有文件都是二进制文件)文本文件

主要由“可见字符”组成

也有一些“不可见字符”(如Tab、回车换行符等)大多数不可见字符也有其视觉作用

文本文件还涉及“编码”(encoding),因为字符串是有编码的,而文本文件可以看作字符串的持久化存储方式文本文件的编码

ASCII

、ISO-8859-1

Unicode

UTF-8

GB2312、GBK、GB18030大多数文本文件编辑器都支持多种编码编辑器一般也支持编码的转换Go语言的代码文件本质上也是文本文件文件的基本操作——打开、读取、关闭

fileT,

errT

:=

os.Open(`c:\test\abc.txt`)

if

errT

!=

nil

{

t.Printfln("打开文件时发生错误:%v",

errT.Error())

return

}

defer

fileT.Close()

dataT

:=

make([]byte,

100)

countT,

errT

:=

fileT.Read(dataT)

if

errT

!=

nil

{

t.Printfln("从文件中读取数据时发生错误:%v",

errT.Error())

return

}

t.Printfln("读取了%d个字节:%#v,对应的字符串是%q",

countT,

dataT[:countT],

dataT[:countT])

t.Printfln("字符串:%v",

string(dataT[:countT]))从较大的文本文件中读取完整内容totalCountT

:=

0totalDataT

:=

make([]byte,

0,

100)

bufT

:=

make([]byte,

5)

for

{

countT,

errT

:=

fileT.Read(bufT)

if

errT

!=

nil

{

if

errT

==

io.EOF

{

break

}

t.Printfln("从文件中读取数据时发生错误:%v",

errT.Error())

return

}

totalDataT

=

append(totalDataT,

bufT[:countT]...)

totalCountT

+=

countT}

t.Printfln("一共读取了%d个字节:%#v,对应的字符串是%q",

totalCountT,

totalDataT[:totalCountT],

totalDataT[:totalCountT])

t.Printfln("字符串:%v",

string(totalDataT[:totalCountT]))使用固定大小的缓冲区少量多次读取简化的读取完整文本的方法//

LoadStringFromFile

从文件中读取所有内容并返回为字符串,如果出错则返回defaultA参数指定的字符串func

LoadStringFromFile(fileNameA

string,

defaultA

string)

string

{

fileT,

err

:=

os.Open(fileNameA)

if

err

!=

nil

{

return

defaultA

}

defer

fileT.Close()

fileContentT,

err

:=

ioutil.ReadAll(fileT)

if

err

!=

nil

{

return

defaultA

}

return

string(fileContentT)}一次读取所有的字节将字节转换为字符串更简单的读取完整文本的方法//

LoadStringFromFile

从文件中读取所有内容并返回为字符串,如果出错则返回defaultA参数指定的字符串func

LoadStringFromFile(fileNameA

string,

defaultA

string)

string

{

fileContentT,

err

:=

ioutil.ReadFile(fileNameA)

if

err

!=

nil

{

return

defaultA

}

return

string(fileContentT)}Go1.6版本之后,也可以用os.ReadFile从文本文件中读取指定数量的行var

buf

strings.Builder

reader

:=

bufio.NewReader(fileT)

limitT

:=

0

for

true

{

strT,

err

:=

reader.ReadString('\n')

if

err

!=

nil

{

break

}

buf.WriteString(strT)

limitT++

if

(limitA

>

0)

&&

(limitT

>=

limitA)

{

break

}}

return

buf.String()将字符串写入文本文件//

SaveStringToFile

将字符串存入文件,如有原来有同名文件则其内容将被冲掉func

SaveStringToFile(strA

string,

fileA

string)

string

{

fileT,

errT

:=

os.Create(fileA)

if

errT

!=

nil

{

return

errT.Error()

}

defer

fileT.Close()

writerT

:=

bufio.NewWriter(fileT)

writerT.WriteString(strA)

writerT.Flush()

return

""}要点:1、创建新文件2、缓冲读写3、保存前刷新缓存向已有的文本文件中追加内容//

AppendStringToFile

向文件中追加字符串,如果文件不存在则新建该文件后再追加func

AppendStringToFile(strA

string,

fileNameA

string)

string

{

fileT,

errT

:=

os.OpenFile(fileNameA,

os.O_RDWR|os.O_CREATE|os.O_APPEND,

0666)

if

errT

!=

nil

{

return

errT.Error()

}

defer

fileT.Close()

writerT

:=

bufio.NewWriter(fileT)

writerT.WriteString(strA)

writerT.Flush()

return

""}使用加了标志位的os.OpenFile函数移动文件指针来向文件中追加内容s

:=

"\n第六行内容\n第七行内容"

fileT,

errT

:=

os.OpenFile("c:\\test\\save.txt",

os.O_RDWR,

0666)if

errT

!=

nil

{

t.Printfln("打开文件时发生错误:%v",

errT.Error())

return}

defer

fileT.Close()

oldSizeT,

errT

:=

fileT.Seek(0,

io.SeekEnd)

if

errT

!=

nil

{

t.Printfln("移动文件指针时发生错误:%v",

errT.Error())

return}

t.Printfln("原有文件大小:%v个字节",

oldSizeT)

_,

errT

=

fileT.Write([]byte(s))if

errT

!=

nil

{

t.Printfln("追加写入文件时发生错误:%v",

errT.Error())

return}

t.Printfln("已成功将字符串%#v追加至文件。",

s)判断文件或目录是否存在//

FileExists

判断文件或目录是否存在func

FileExists(fileNameA

string)

bool

{

_,

errT

:=

os.Stat(fileNameA)

return

errT

==

nil

||

os.IsExist(errT)}判断是否是文件//

IsFile

判断路径名是否是文件func

IsFile(fileNameA

string)

bool

{

f,

errT

:=

os.Open(fileNameA)

if

errT

!=

nil

{

return

false

}

defer

f.Close()

fi,

err

:=

f.Stat()

if

err

!=

nil

{

return

false

}

if

mode

:=

fi.Mode();

mode.IsRegular()

{

return

true

}

else

{

return

false

}}判断是否是目录//

IsDirectory

判断路径名是否是目录func

IsDirectory(dirNameA

string)

bool

{

f,

err

:=

os.Open(dirNameA)

if

err

!=

nil

{

return

false

}

defer

f.Close()

fi,

err

:=

f.Stat()

if

err

!=

nil

{

return

false

}

if

mode

:=

fi.Mode();

mode.IsDir()

{

return

true

}

else

{

return

false

}}删除文件fileNameT

:=

"c:\\test\\save.txt"

if

!t.FileExists(fileNameT)

{

t.Printfln("文件

%v

不存在",

fileNameT)

return}

errT

:=

os.Remove(fileNameT)

if

errT

!=

nil

{

t.Printfln("删除文件时发生错误:%v",

errT.Error())

return}

t.Printfln("已成功删除文件%v。",

fileNameT)删除整个目录dirNameT

:=

"c:\\test"

if

!t.FileExists(dirNameT)

{

t.Printfln("目录

%v

不存在",

dirNameT)

return}

errT

:=

os.RemoveAll(dirNameT)

if

errT

!=

nil

{

t.Printfln("删除目录时发生错误:%v",

errT.Error())

return}

t.Printfln("已成功删除目录%v。",

dirNameT)创建新目录和新文件dirNameT

:=

"c:\\test\\sub1"

errT

:=

os.Mkdir(dirNameT,

0777)

if

errT

!=

nil

{

t.Printfln("创建目录时发生错误:%v",

errT.Error())

return}

t.Printfln("已成功删除目录%v。",

dirNameT)

fileT,

errT

:=

os.OpenFile("c:\\test\\sub1\\test.txt",

os.O_CREATE,

0666)

if

errT

!=

nil

{

t.Printfln("创建文件时发生错误:%v",

errT.Error())

return}

defer

fileT.Close()文件的移动或改名oldFileNameT

:=

"c:\\test\\sub1\\test.txt"newFileNameT

:=

"c:\\test\\new.txt"

errT

:=

os.Rename(oldFileNameT,

newFileNameT)

if

errT

!=

nil

{

t.Printfln("移动文件时发生错误:%v",

errT.Error())

return}

t.Printfln("已成功移动文件

%v

%v。",

oldFileNameT,

newFileNameT)获取文件的大小fileInfoT,

errT

:=

os.Stat(`c:\test\long.txt`)

if

errT

!=

nil

{

t.Printfln("获取文件信息时发生错误:%v",

errT.Error())

return}

t.Printfln("文件的大小为:%v",

fileInfoT.Size())文件拷贝(复制)oldFileNameT

:=

"c:\\test\\long.txt"newFileNameT

:=

"c:\\test\\sub1\\copiedFile.txt"

oldFileT,

errT

:=

os.Open(oldFileNameT)if

errT

!=

nil

{}defer

oldFileT.Close()

newFileT,

errT

:=

os.OpenFile(newFileNameT,

os.O_CREATE|os.O_RDWR,

0666)if

errT

!=

nil

{}defer

newFileT.Close()

bufT

:=

make([]byte,

5)for

{

countT,

errT

:=

oldFileT.Read(bufT)

if

errT

!=

nil

{

if

errT

==

io.EOF

{

break

}

t.Printfln("从源文件中读取数据时发生错误:%v",

errT.Error())

return

}

_,

errT

=

newFileT.Write(bufT[:countT])

if

errT

!=

nil

{

t.Printfln("将数据写入新文件时发生错误:%v",

errT.Error())

return

}}文本文件编码转换——GB18030–UTF-8//

ConvertBytesFromGB18030ToUTF8

转换GB18030编码的字节切片为UTF-8编码func

ConvertBytesFromGB18030ToUTF8(srcA

[]byte)

[]byte

{

bufT

:=

make([]byte,

len(srcA)*4)

transformer

:=

simplifiedchinese.GB18030.NewDecoder()

countT,

_,

errT

:=

transformer.Transform(bufT,

srcA,

true)

if

errT

!=

nil

{

return

nil

}

return

bufT[:countT]}需引用/x/text/encoding/simplifiedchinese包文本文件编码转换——UTF-8–GB18030//

ConvertBytesFromUTF8ToGB18030

转换UTF-8编码的字节切片为GB18030编码func

ConvertBytesFromUTF8ToGB18030(srcA

[]byte)

[]byte

{

bufT

:=

make([]byte,

len(srcA)*4)

transformer

:=

simplifiedchinese.GB18030.NewEncoder()

countT,

_,

errT

:=

transformer.Transform(bufT,

srcA,

true)

if

errT

!=

nil

{

return

nil

}

return

bufT[:countT]}VSCode编辑器中编码的转换文本排序

linesT

:=

[]string{"abc",

"rst",

"def",

"123"}

sort.Sort(sort.StringSlice(linesT))

fmt.Printf("%v\n",

linesT)sort.Sort(sort.Reverse(sort.StringSlice(linesT)))降序排序自定义排序规则type

NewStringSlice

[]string

func

(v

NewStringSlice)

Len()

int

{

return

len(v)}

func

(v

NewStringSlice)

Swap(i,

j

int)

{

v[i],

v[j]

=

v[j],

v[i]}

func

(v

NewStringSlice)

Less(i,

j

int)

bool

{

if

v[i]

==

""

&&

v[j]

!=

""

{

return

false

}

if

v[i]

!=

""

&&

v[j]

==

""

{

return

true

}

return

v[i]

<

v[j]}效果是空格最大自定义排序规则效果func

main()

{

fileNameT

:=

`c:\test\long.txt`

lines

:=

t.LoadStringListFromFile(fileNameT)

stringSlice

:=

NewStringSlice(lines)

if

lines

==

nil

{

t.Printfln("从文件%v中读取字符串列表时发生错误",

fileNameT)

}

sort.Sort(sort.Reverse(stringSlice))

t.Printfln("排序后的字符串列表(行列表):%#v",

lines)}排序后的字符串列表(行列表):[]string{"","大家玩的都很高兴。","abc2136782368xyz","3.14159265358979"}超大文本文件排序

将大文件拆分成小文件

对拆分后的小文件逐个内部排序同时打开所有小文件,并新建一个结果文件

依次读取各小文件头一行进行比较,最大(或最小,根据升序还是降序要求)的追加写入结果文件中

不断执行第4步,直至所有文件被读取完毕文本查重、去重第一种:查找字符串中重复出现的子串第二种:查找多行文本中重复的行第三种:检查整个字符串与其他字符串的相似度,一般用于互联网上论文查重、文章版权所属的查询等目录导航9.2Go语言中二进制文件的处理Contents文本查重、去重任何文件其实都可以被看作是“二进制文件”二进制文件由一个个字节组成二进制文件一般是指直接存储数据而不是可显示字符的文件二进制文件优点是节省空间、处理速度快缺点是可读性不强、不便于手动进行修改常见二进制文件有图片、音频、视频文件等将不同类型的数据写入二进制文件n1

:=

64f1

:=

12.8b1

:=

falses1

:=

"abc123"point1

:=

Point{X:

1.8,

Y:

3.5}

bufT

:=

new(bytes.Buffer)

errT

:=

binary.Write(bufT,

binary.LittleEndian,

int64(n1))if

errT

!=

nil

{

log.Fatalf("写入数据n1时发生错误:%v",

errT.Error())}

binary.Write(bufT,

binary.LittleEndian,

f1)binary.Write(bufT,

binary.LittleEndian,

b1)binary.Write(bufT,

binary.LittleEndian,

[]byte(s1))binary.Write(bufT,

binary.LittleEndian,

point1)

t.Printfln("bufT中内容:%#v",

bufT.Bytes())

ioutil.WriteFile(`c:\test\binaryFile1.bin`,

bufT.Bytes(),

0666)从二进制文件读取不同类型的数据bytesT,

errT

:=

ioutil.ReadFile(`c:\test\binaryFile1.bin`)

if

errT

!=

nil

{

log.Fatalf("从文件中读取数据时发生错误:%v",

errT.Error())}

var

n2

int64var

f2

float64var

b2

boolvar

s2buf

[]byte

=

make([]byte,

6)var

point2

Point

newBufT

:=

bytes.NewReader(bytesT)

errT

=

binary.Read(newBufT,

binary.LittleEndian,

&n2)if

errT

!=

nil

{

log.Fatalf("读入数据n2时发生错误:%v",

errT.Error())}

binary.Read(newBufT,

binary.LittleEndian,

&f2)binary.Read(newBufT,

binary.LittleEndian,

&b2)binary.Read(newBufT,

binary.LittleEndian,

&s2buf)binary.Read(newBufT,

binary.LittleEndian,

&point2)使用encoding/gob包来保存数据n1

:=

64f1

:=

12.8b1

:=

falses1

:=

"abc123"person1

:=

Person{Name:

"张三",

Age:

28,

Gender:

"男",

Height:

170,

Weight:

60}

bufT

:=

new(bytes.Buffer)

encoderT

:=

gob.NewEncoder(bufT)

errT

:=

encoderT.Encode(n1)

if

errT

!=

nil

{

log.Fatalf("写入数据n1时发生错误:%v",

errT.Error())}

encoderT.Encode(f1)encoderT.Encode(b1)encoderT.Encode(s1)encoderT.Encode(person1)

ioutil.WriteFile(`c:\test\binaryFile2.bin`,

bufT.Bytes(),

0666)使用encoding/gob包来读取数据bytesT,

errT

:=

ioutil.ReadFile(`c:\test\binaryFile2.bin`)if

errT

!=

nil

{

log.Fatalf("从文件中读取数据时发生错误:%v",

errT.Error())}

var

n2

intvar

f2

float64var

b2

boolvar

s2

stringvar

person2

Person

newBufT

:=

bytes.NewBuffer(bytesT)decoderT

:=

gob.NewDecoder(newBufT)

errT

=

decoderT.Decode(&n2)if

errT

!=

nil

{

log.Fatalf("读入数据n2时发生错误:%v",

errT.Error())}

decoderT.Decode(&f2)decoderT.Decode(&b2)decoderT.Decode(&s2)decoderT.Decode(&person2)自定义文件格式文件头(0x07、0x01、0x00、0x08共4个字节)记录条数(int64类型,占用8个字节)第1条记录(Customer类型,长度不固定,下同)第2条记录……最后一条记录自定义记录的数据结构//

Customer

是表示客户信息的结构类型type

Customer

struct

{

Name

string

Age

int

Gender

string

Mobile

string

Email

string}

写入自定义记录customers

:=

make([]Customer,

3)

customers[0]

=

Customer{Name:

"张三",

Age:

28,

Gender:

"男",

Mobile:

"1322226688",

Email:

"zhangsan@"}customers[1]

=

Customer{Name:

"李四",

Age:

24,

Gender:

"女",

Mobile:

,

Email:

"lisi@"}

//

创建ctm格式的文件用于写入客户信息记录file1T,

_

:=

os.Create(`c:\test\customerInfo.ctm`)

//

创建编码器对象encoderT

:=

gob.NewEncoder(file1T)

//

写入文件头file1T.Write([]byte{0x07,

0x01,

0x00,

0x08})

//

写入记录条数(长度)encoderT.Encode(int64(len(customers)))

//

循环写入所有记录for

_,

v

:=

range

customers

{

encoderT.Encode(v)}

//

关闭文件file1T.Close()省略了异常处理读取自定义记录file2T,

_

:=

os.Open(`c:\test\customerInfo.ctm`)defer

file2T.Close()

decoderT

:=

gob.NewDecoder(file2T)

//

分配用于存储文件头的字节切片变量fileHeadT

:=

make([]byte,

4)

//

读取文件头file2T.Read(fileHeadT)t.Printfln("文件头:%#v",

fileHeadT)

//

判断是否是正确的文件头if

bytes.Compare(fileHeadT,

[]byte{0x07,

0x01,

0x00,

0x08})

!=

0

{

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论