今天我们来说一下在go语言中,如何对本地文件进行操作。
一、创建文件
我们在将数据存储到文件之前,首先要在磁盘中创建文件。
Create()函数在GO语言中,提供我们创建文件使用。我们现在讲的都是基于文本文件的存储。
除了文本文件外,计算机中还有一种存储格式叫二进制文件,如:音频、视频、图片等等。
创建文件的过程:
1、我们在创建文件之前,首先要导入“os” 包。创建文件的函数都在该包中。
2、指定创建文件存放路径以及文件名称。
3、执行Create()函数,进行文件的创建
4、关闭文件操作
package main
import (
"fmt"
"os"
)
func main() {
//路径又分为 相对路径 绝对路径
//绝对路径: windows系统中,从盘符开始到文件的位置如:(D:\go\文件操作)
// linux 系统中是以根目录/开始的。
//绝对路径 相对某一个文件的位置。以当前文件所在目录开始。如(./)表示当前该文件所在的目录../为上级目录
// \\ 是一个转义字符 [\] 在一般文件操作中都是以 [/]
file,error:=os.Create("D:/go_test/file/a.txt")
//error 中如果有值
if error != nil{
fmt.Println(error)
fmt.Println("文件创建失败")
return //如果return出现在主函数中,表示程序的结束。
}
//defer 延迟调用,关闭文件、
//文件如果不关闭影响:
//1、占用内存和缓冲区
//2、文件的打开上线为 65535
defer file.Close()
fmt.Println("文件创建成功")
}
结果:
文件创建成功
在相应的目录位置,创建出a.txt文件
上面代码中,file 是一个文件指针 相当于 var file * File
在文件操作中,使用so.Create()函数创建文件时,如果文件不存在,会创建一个新文件。
如果文件已经存在,那么会覆盖创建,覆盖掉原来的内容。
二、写入文件
文件的写入,WriteString( )方法、
package main
import (
"fmt"
"os"
)
func main() {
file,error:=os.Create("D:/go_test/file/a.txt")
//error 中如果有值
if error != nil{
fmt.Println(error)
fmt.Println("文件创建失败")
return
}
defer file.Close()
//写入文件
//在windows 中,写入文本文件换行为 \r\n
//在linux 中,写入文本文件换行为 \n
n,_:=file.WriteString("写入文件测试\r\n")
//n返回值,返回写入个数
fmt.Println(n)
m,_=file.WriteString("第二行写入测试")
fmt.Println(m)
}
结果:
20
21
在go语言中,一个汉字,是3个字符。
写入文件的第二种方式:
package main
import (
"fmt"
"os"
)
func main() {
file,error:=os.Create("D:/go_test/file/a.txt")
//error 中如果有值
if error != nil{
fmt.Println(error)
fmt.Println("文件创建失败")
return
}else{
fmt.Println("创建文件成功!")
}
defer file.Close()
b:=[]byte{'1','2','3','4'}
n,_:=file.Write(b)
fmt.Println(n)
}
结果:
写入文件成功!
4
上面这种方式,是使用文件对象.write(字符切片) 的方式写入文件,可以看到这种方式有些麻烦 。
做一下简单的修改:
package main
import (
"fmt"
"os"
)
func main() {
file,error:=os.Create("D:/go_test/file/a.txt")
//error 中如果有值
if error != nil{
fmt.Println(error)
fmt.Println("文件创建失败")
return
}else{
fmt.Println("创建文件成功!")
}
defer file.Close()
//b:=[]byte{'1','2','3','4'}
str:="1234"
b:=[]byte(str)
n,_:=file.Write(b)
fmt.Println(n)
}
结果:
写入文件成功!
4
可以看到,我们做了小改动以后,跟上面那种写入方式一样。
这里说明一下,在go语言中,string 字符串和字符切片允许转换。
第三种文件,写入方式:
package main
import (
"fmt"
"os"
)
func main() {
//os.OpenFile(文件路径名称,打开模式,打开权限)
//OpenFile 不能创建新文件
file,error:=os.OpenFile("D:/go_test/file/a.txt", os.O_RDWR,6)
if error != nil{
fmt.Println(error)
fmt.Println("文件创建失败")
return
}else{
fmt.Println("创建文件成功!")
}
defer file.Close()
b:=[]byte("OpenFile文件测试")
//当使用WriteAt()进行指定位置,写入文件时,会覆盖文件内容。
file.WriteAt(b,0)
}
当我们出入文件时,还可以获取,文件内容的位置信息:
package main
import (
"fmt"
"io"
"os"
)
func main() {
//os.OpenFile(文件路径名称,打开模式,打开权限)
//OpenFile 不能创建新文件
file,error:=os.OpenFile("D:/go_test/file/a.txt", os.O_RDWR,6)
if error != nil{
fmt.Println(error)
fmt.Println("文件创建失败")
return
}else{
fmt.Println("打开文件成功!")
}
defer file.Close()
//获取文件字符个数信息,从开始到末尾
n,_:=file.Seek(0, io.SeekEnd)
fmt.Println(n)
//b:=[]byte("OpenFile文件测试")
//当使用WriteAt()进行指定位置,写入文件时,会覆盖文件内容。
//file.WriteAt(b,0)
}
结果:得到文件中的字符个数信息
20
然后使用wirteAt(插入内容,插入字符位置),来进行文件内容写入操作。可以写入在任意位置内。
三、读取文件
读取文件过程:
1、打开要读取的文件
2、对文件进行读取
3、关闭文件
package main
import (
"fmt"
"os"
)
func main() {
//os.Open(文件路径名称),以只读方式打开文件
file,error:=os.Open("D:/go_test/file/a.txt")
if error != nil{
fmt.Println(error)
fmt.Println("打开文件失败")
return
}else{
fmt.Println("打开文件成功!")
}
defer file.Close()
b:=make([]byte,1024)
//读取文件
file.Read(b)
fmt.Println(b)
}
结果:
[79 112 101 110 70 105 108 101 230 150 135 228 187 182 230 181 139 232 175 149 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
这里我们设置接收读取数据大小,为1024个字节,可以看到,我们读取出来的数据,都是是二进制数据
如何转成我们所需要的文本数据呢?
fmt.Println(string(b))
b:=make([]byte,1024)
//读取文件
file.Read(b)
fmt.Println(b)
fmt.Println(string(b))
结果:
[239 187 191 79 112 101 110 70 105 108 101 84 101 115 116 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
OpenFileTest
OpenFile( )读取文件这个函数有三个参数,第一个参数表示打开文件的路径,第二个参数表示模式,常见的模式有
O_RDONLY(只读模式),O_WRONLY(只写模式), O_RDWR( 可读可写模式),O_APPEND(追加模式)。
第三个参数,表示权限,取值范围(0-7)
表示如下:
0:没有任何权限
1:执行权限(如果是可执行文件,是可以运行的)
2:写权限
3:写权限与执行权限
4:读权限
5:读权限与执行权限
6:读权限与写权限
7:读权限,写权限,执行权限
读取文件方式跟上述方式几乎一样,只是在openfile时,需要多加几个参数。参数表示如上诉所示。
读取文件2:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//os.Open(文件路径名称),以只读方式打开文件
file,error:=os.Open("D:/go_test/file/a.txt")
if error != nil{
fmt.Println(error)
fmt.Println("打开文件失败")
return
}else{
fmt.Println("打开文件成功!")
}
defer file.Close()
//创建切片缓冲区
r:=bufio.NewReader(file)
//读取文件内容
b,_:=r.ReadBytes('\n')
fmt.Println(string(b))
}
结果:
OpenFileTest
我们按行读取数据。需要用到bufio包中的ReadByutes函数。创建缓冲区,也就是我们需要存储数据的区域。将从文件中读取的数据,存储在缓冲区中,然后将缓冲区的数据读取出来。提供缓冲区的原因:为了缓和CPU与磁盘之间速度不匹配的矛盾。文件缓冲区是用来暂时存储读写期间文件数据而在内存区域中预留的一定空间。
而我们在使用ReadBytes( )函数时,传递的参数是‘\n’,表示遇到’\n’就结束。这里传递的参数,可以不是'\n'。是任意字符都可以。
如果在文件截取中,没有到我们要找的标志位,到文件末尾也会自动停止。
这种方式也就是我们可以读取文件中的行。