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. SOJ1711 题解

    题意 给定 \(n\) 个在数轴的区间 \([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\). 定义 \(I(x)\) 为所有包含 \([x,x+1]\) 的区间形成的集合,即 ...

  2. vuexy full-wersion项目安装报错问题处理

    npm install grpc@1.23.3 --ignore-scripts npm rebuild node-sass

  3. 【剑指Offer】【数组】顺时针打印矩阵

    题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1 ...

  4. VS2012下没有ADO.NET实体数据模型

    在C盘下搜"EFTools.msi"然后退出VS,点击修复在打开VS,数据下就有了

  5. pyqt5 弹窗大全--修复版

    1 from PyQt5.QtWidgets import * 2 from PyQt5.QtCore import Qt, pyqtSignal, QTimer 3 4 5 class MyWind ...

  6. oracle 数据恢复 回滚数据

    1.查询你执行update 语句之前的数据 精确到什么时间 select * from 表名 as of timestamp to_timestamp('2017-07-21 17:16:38', ' ...

  7. <小李飞刀>系列 随笔

    1.多情剑客无情剑 古龙的作品在电视上只看过电影版的陆小凤传奇,对古龙的作品也没有过系统的了解,初读时听到了李寻欢的名字,突然感觉可惜.觉得如此早就读到这种级别的小说有些暴殄天物,不过也算是以白纸状态 ...

  8. Opengl数学markdown

    # opengl数学 $$\begin{Bmatrix} {A_{x}}\\ {A_{y}}\\ {A_{z}}\\ \end{Bmatrix} * \begin{Bmatrix} {B_{x}}\\ ...

  9. LayUI 简单的全选和反选小例子

    比较简单实用,直接上代码,主要就是  lay-filter="ischange"   触发事件和  checkbox 的 class="ids" 对上就行: H ...

  10. unable to access 'http://*****/': The requested URL returned error: 414

    git拉取gitlab项目: unable to access 'http://git.yijiago.com/meimeng/lsyjg_java.git/': The requested URL ...