




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电竞职业战队孵化中心行业跨境出海项目商业计划书
- 智能变色塑料户外椅垫企业制定与实施新质生产力项目商业计划书
- 河北梆子表演AI应用企业制定与实施新质生产力项目商业计划书
- 电影、电视艺术评论AI应用行业跨境出海项目商业计划书
- 2025至2031年中国南官帽椅行业投资前景及策略咨询研究报告
- 2025至2031年中国切肉大刀行业投资前景及策略咨询研究报告
- 棒球与在线平台行业深度调研及发展项目商业计划书
- 物理治疗诊所行业跨境出海项目商业计划书
- 民族歌舞汇演行业深度调研及发展项目商业计划书
- 机场消防控制室值班人员职责
- 道化学(火灾爆炸危险指数评价法)
- 消防工程火灾自动报警及联动控制系统施工
- 2024年江西省高考地理试卷真题(含答案)
- 《丝绸服饰文化》课件-第一讲丝绸的起源与发展
- 安全文明施工措施费(终版)
- 2021年湖南省普通高中学业水平考试数学试卷及答案
- DL-T5588-2021电力系统视频监控系统设计规程
- 四川省成都市 2024年高一下数学期末考试试题含解析
- DZ∕T 0382-2021 固体矿产勘查地质填图规范(正式版)
- 《研学旅行课程设计》课件-研学课程方案设计
- 开票申请表模板
评论
0/150
提交评论