Go的Io流

获取文件信息

//获取文件
fileinfo, err := os.Stat("./aa.txt")//相对绝对路径都可以
if err != nil {
fmt.Println(err)
return
}
fmt.Println(fileinfo) //所有的信息都在其中
fmt.Println(fileinfo.Name()) //获取文件名称
fmt.Println(fileinfo.Mode()) //获取文件权限
fmt.Println(fileinfo.IsDir()) //判断文件是不是文件夹
fmt.Println(fileinfo.ModTime()) //获取文件修改时间
fmt.Println(fileinfo.Size()) //获取文件大小
fmt.Println(fileinfo.Sys()) //获取文件的系统属性
//不过此方法需要通过反射才能使用

文件权限表示

符号表示

type	owner		group		others

type:文件类型 -文件  d文件夹

八进制表示

r 004	w 003	x 001 -000
777是最大权限

创建文件与目录

创建目录

//创建目录
err := os.Mkdir("d://a", os.ModePerm)
//mkdir不能创建多级目录 比如 "d://v//c" 若c前面的路径不存在就会报错
if err != nil {
fmt.Println(err)
return
}
fmt.Println("目录创建成功")

创建多级目录

//创建多级目录
err := os.MkdirAll("d://c//e//d", 777)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("创建成功")

删除文件

//remove只能删除空目录
err := os.Remove("d://c")
if err != nil {
fmt.Println(err)
fmt.Println("删除是吧")
//return
}
fmt.Println("删除成功") //直接删除 不管该目录下是否有内容 慎用
err2 := os.RemoveAll("d://c")
if err2 != nil {
fmt.Println(err2)
fmt.Println("删除失败")
return
}
fmt.Println("删除成功")

创建文件

//创建文件  每次执行都会覆盖创建 内容也会空内容覆盖
file, err := os.Create("./bb.txt")
if err != nil {
fmt.Println(err)
}
fmt.Println(file.Name())
//删除文件
err=os.Remove("./bb.txt")
fmt.Println(err)

IO读取文件内容

获取文件连接有两种方式

//1.获取文件对象 建立连接  第一种方式

	file, err := os.Open("./aa.txt")
if err != nil {
fmt.Println(err)
return
}
//2.关闭连接
defer file.Close() //使用defer 使得程序全部运行完毕再关闭 //第二种这种建立连接方式 可以指定权限 打开模式方式 这样就可以操作文件的更多细节
//openfile(文件路径,文件可操作动作,文件权限)
file2, err2 := os.OpenFile("./aa.txt", os.O_RDONLY|os.O_WRONLY, os.ModePerm)
if err2 != nil {
fmt.Println(err2)
return
}
//若以及确定文本本身的权限足够 比如已经可读可写 就不用此种方式建立文件连接了 //关闭连接
defer file2.Close()

两种方式的挑选

fileinfo, _ := os.Stat("aa.txt")
fmt.Println(fileinfo.Mode())
//使用stat获取文件信息 mode获取文件权限信息
//若文件本身可以确定其权限足够,则可直接才有第一种 不够不二中

PS:更多会直接才有第二种方式,因为更加灵活

读取文件对象的内容

//3.使用read方法读取内容
bs := make([]byte, 1, 1024)
n, err3 := file.Read(bs) //n是read方法读取内容的数量 并将内容放入bs切片中
fmt.Println(err3)
fmt.Println(n)
fmt.Println(string(bs)) //bs中的元素是byte类型 需要强制转换一下

read方法需要传入一个byte切片类型读取内容,其N长度就是每次读取文件的内容的长度,

//第一次读取
n, err3 := file.Read(bs)
fmt.Println(err3)
fmt.Println(n)
fmt.Println(string(bs)) //接着第一次读取的位置继续读取
n, err3 := file.Read(bs)
fmt.Println(err3)
fmt.Println(n)
fmt.Println(string(bs)) //当n=0时说明已经将文件内容全部读完,bs中只能打印出最后一次读取的内容 不在被覆盖更新

for 循环读取内容

bs := make([]byte, 1, 1024)
//这里直接使用for循环读取
for {
n, _ := file.Read(bs)
if n == 0 {
return
}
fmt.Print(string(bs)) }

IO写入内容

//这里不加上os.O_append下 每次执行都会把第一行数据清空在写入
file, err := os.OpenFile("aa.txt", os.O_WRONLY|os.O_RDONLY, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
defer file.Close() br := []byte{65, 66, 67, 68, 69}
n, err2 := file.Write(br)
if err2 != nil {
fmt.Println(err2)
return
}
fmt.Println(n)
//这里添加了apped动作 每次执行都会在全部内容末尾追加写入的内容
file, err := os.OpenFile("aa.txt", os.O_WRONLY|os.O_RDONLY|os.O_APPEND, os.ModePerm)
if err != nil {
fmt.Println(err)
return
}
defer file.Close() br := []byte{65, 66, 67, 68, 69}
n, err2 := file.Write(br)
if err2 != nil {
fmt.Println(err2)
return
}
fmt.Println(n)

字符串直接写入

//可以直接写入字符串
n, err = file.WriteString("nihao,我是中国人")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(n)

不过一般使用 切片读取写入较多

文件复制

func main() {
sour := "./售后联系方式.png"
dest := "d://copy3.png"
//copy(sour, dest, 1024) //copy2(sour, dest)
copy3(sour, dest)
} func copy(sour, dest string, bufsize int) {
//获取源文件对象
sourFile, err := os.Open(sour)
if err != nil {
fmt.Println(sourFile)
return
}
defer sourFile.Close() //获取目标对象且给予权限动作 os.O_CREATE当文件不存在时 会自动创建 不需要加判断 create了
destFile, err2 := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, os.ModePerm)
if err2 != nil {
fmt.Println(err2)
return
}
defer destFile.Close() //文件缓冲区
buff := make([]byte, bufsize) for {
//读取内容
n, err3 := sourFile.Read(buff)
if err3 == io.EOF || n == 0 {
fmt.Println("文件复制完毕")
break
} //写入内容
_, err3 = destFile.Write(buff[:n])
if err3 != nil {
fmt.Println(err3) } } } func copy2(sour, dest string) {
sourFile, err := os.Open(sour)
if err != nil {
fmt.Println(sourFile)
return
}
defer sourFile.Close() //获取目标对象且给予权限动作 os.O_CREATE当文件不存在时 会自动创建 不需要加判断 create了
destFile, err2 := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, os.ModePerm)
if err2 != nil {
fmt.Println(err2)
return
}
defer destFile.Close() //调用系统copy方法
wf, _ := io.Copy(destFile, sourFile)
fmt.Println("文件大小:", wf)
} // 此方法是一次性写入写出 不适用大型文件
func copy3(sour, dest string) {
rfbuff, _ := os.ReadFile(sour)
os.WriteFile(dest, rfbuff, 777)
}

Seeker接口

里面包装了seek方法

type Seeker interface{
Seek(offset int64,whence int)(int64,error)
}

seek(offset,whence)设置指针光标的位置,读写文件

offset:偏移量

whence:从哪里开始计算

​ 0 seekStart 相对于文件开头

​ 1 seekCurrent 相对于当前光标的位置

​ 2 seekend 相对于文件末尾

file, _ := os.OpenFile("./aa.txt", os.O_RDWR, os.ModePerm)
defer file.Close() //业务
file.Seek(2, io.SeekStart) //偏移量2个从文件开头算起
buf := []byte{0, 8}
file.Read(buf)
fmt.Println(string(buf)) file.Seek(3, io.SeekCurrent) //偏移量3 从上一次光标的位置算起
file.Read(buf)
fmt.Println(string(buf)) file.Seek(0, io.SeekEnd) //偏移量0 从文件末尾开始算
file.WriteString("我肯定在最后")

断点续传

文件过大如何缩短时间

文件传输中断 如何续传

seek方法可以实现

/*
实现断点续传
思路:主要记住上一次已经传递了多少数据,那就可以创建一个临时文件,记录已经传递的数据量,当恢复传递的时候,
先从临时文件读取上次已经传递的数据量,然后通过Seek()方法,设置到该读和写的位置,再继续传输数据
*/ func main() {
//传输源文件
sourFile := "./copy.png"
//传输目的地
destFile := "D:\\new.png"
//临时记录文件
tempFile := "./temp.txt" //建立文件连接
file1, _ := os.Open(sourFile)
file2, _ := os.OpenFile(destFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
file3, _ := os.OpenFile(tempFile, os.O_CREATE|os.O_RDWR, os.ModePerm) //关闭连接
defer file1.Close()
defer file2.Close() //1.读取临时文件中记录的数据 //设置光标的位置
file3.Seek(0, io.SeekStart)
//缓冲区域
buff := make([]byte, 1024, 1024)
//读取file3文件内容
n, _ := file3.Read(buff)
//内容虽然是数字 但是返回的是string类型
countStr := string(buff[:n]) //光标的位置
fmt.Println("countStry:", countStr)
count, _ := strconv.ParseInt(countStr, 10, 64) //获取到了光标的位置那么源文件与目标文件也要从此开始
file1.Seek(count, io.SeekStart)
file2.Seek(count, io.SeekStart) bufData := make([]byte, 1024, 1024)
//记录总共记录的多少数据
total := int(count)
for {
redn, err := file1.Read(bufData)
if err == io.EOF {
fmt.Println("文件读取完毕")
//这个时候再关闭临时文件 保险
file3.Close()
os.Remove(tempFile)
break
}
wrin, _ := file2.Write(bufData[:redn])
total += wrin
//将传输的进度记录到临时文件中
file3.Seek(0, io.SeekStart)
file3.WriteString(strconv.Itoa(total)) //if total > 1000026 {
// panic("dd")
//} }
}

bufio包

这个包可以大幅提高文件读写的效率

增加输入出中的缓冲区 理解同java的inputstreambuff一致

func main() {
file1, _ := os.OpenFile("./aa.txt", os.O_RDWR, os.ModePerm)
defer file1.Close() //bufio
reder := bufio.NewReader(file1)
buff := make([]byte, 1024)
n, _ := reder.Read(buff)
fmt.Println(n)
fmt.Println(string(buff[:n])) //读取键盘的输入
ipReader := bufio.NewReader(os.Stdin)
//输入\t也就是回车就结束
str, _ := ipReader.ReadString('\t')
fmt.Println("读取输入:", str) wri := bufio.NewWriter(file1)
//这里只是写入到了缓冲区 如果达不到缓冲区的值 不会主动写入文件中
wn, _ := wri.WriteString("hello") //所以这里需要刷新一下缓冲区
fmt.Println("写入:", wn)
wri.Flush() }

遍历文件夹

func listDir(filepath string) {
dir := filepath
fileinfo, _ := os.ReadDir(dir)
for i, v := range fileinfo {
filename := dir + "\\" + v.Name()
if v.IsDir() {
listDir(filename)
}
fmt.Printf("%d %s", i, filename)
fmt.Println() } }

Go_day08的更多相关文章

随机推荐

  1. 有关箭头函数的this知识

    总结: 结果: 2,箭头函数正确的使用方法. 结果: 总结: 箭头函数不要直接在对象的属性上用.比如上面的函数3.

  2. AI 智能搜索 开源hanlp实现

    AI智能搜索 通过网络资源可知有很多种开源方式实现智能搜索,其中hanlp在GitHub中响应居高 参考链接: https://www.hanlp.com/ Java版:https://github. ...

  3. python 的sys.argv 和 sys.path.append() 用法和PYTHONPATH环境变量

    sys.argv 我们编写一个测试用例test.py ,内容如下 imoprt sys a = sys.argv b = len(sys.argv) c = sys.argv[0] d = sys.a ...

  4. elm上传图片,只能上传一张,隐藏+上传框

    效果: 上传后,隐藏+号,禁止继续上传: 移除当前已上传的后,重新显示+号,可以继续上传: 代码: css : 隐藏上传的 + 号 变量: 注: 利用 hideUpload 控制 + 号的css   ...

  5. TypeScript 元组

    TypeScript 元组 我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组. 元组中允许存储不同类型的元素,元组可以作为参数传 ...

  6. lua中定义变量用and和or连接

    原文链接 最近在写代码中看到lua定义变量有local a = value1 and value2的操作,有些疑问,在此记录一下:当连接两个操作数时,1.对于运算符and,假设它的第一个操作数为假,就 ...

  7. 链式前向星+dijkstra

    https://leetcode-cn.com/problems/network-delay-time/submissions/ // n <= 100 class Solution { int ...

  8. 服务器 安装docker (启动坑了很久才成功)docker-compose

    安装docker: 1.Docker要求CentOS系统的内核版本高于 3.10 ,    通过 uname -r 命令查看你当前的内核版本是否支持安账docker 2.更新yum包: sudo yu ...

  9. python之变量

    什么是变量? 用来记录事务的变化状态,计算机模拟人,就需要具备人类某一个功能.你通过记录我的名字年龄等一系列的身份信息,以此和我进行匹配,确定我就是phoebe这个人. 为什么有变量? 游戏里的英雄角 ...

  10. 尝试改善科研V2

    参考链接: https://fulequn.github.io/2022/09/26/Article202209261/ https://www.xljsci.com/ https://apps.an ...