golang IO流
file一些操作os包下
- FileInfo : 获取文件信息
- Reader : 读
- Write:写
- 文件复制
- mkdir
- create
- remove
Seeker接口
设置光标的位置,读写文件
type Seeker interface {// 1、offset 偏移量 3// 2、whence 如何设置,当前光标的位置。Seek(offset int64, whence int) (int64, error)
}
// 如何让光标在第三个位置?
// 1、找到当前光标在哪里
// a) 文件的头部, 0
// b) 文件的尾部 end
// c) 在任意地方,相对位置。const (SeekStart = 0 // 表示相对于文件的开头SeekCurrent = 1 // 表示相对于当前光标所在的位置SeekEnd = 2 // 相对于文件的末尾
)
关于seek的使用
package mainimport ("fmt""io""os"
)func main() {// 读取文件file, _ := os.OpenFile("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\a.txt",os.O_RDWR, os.ModePerm)// defer closedefer file.Close()// 测试seek// 相对开始位置。io.SeekStart// 相对于文件末尾, io.SeekEndfile.Seek(2, io.SeekStart)buf := []byte{0}file.Read(buf)fmt.Println(string(buf))// 相对于当前位置file.Seek(3, io.SeekCurrent)file.Read(buf)fmt.Println(string(buf))// 在结尾追加内容file.Seek(0, io.SeekEnd)file.WriteString("hahahaha")
}
断点续传
思考几个问题:
1、如果你要传的文件很大,70G,是否有方法可以缩短耗时?
- 将文件拆分
- 同时多线程进行下载
2、如果在文件传递过程中,程序被迫中断(断电、断网、内存满了…),下次重启之后,文件是否还需要重头再传?
- 希望能够继续上传或者下载
3、传递文件的时候,支持暂停和恢复上传?假设这个两个操作分布在重启前后?
- 支持!
file、read、write、seek
思路:
1、需要记住上一次传递了多少数据、temp.txt => 记录
2、如果被暂停或者中断了,我们就可以读取这个temp.txt的记录,恢复上传
3、删除temp.txt
所有人必须要要全部理解的一段代码
package mainimport ("fmt""io""os""strconv"
)// 断点续传
func main() {// 传输源文件地址srcFile := "C:\\Users\\遇见狂神说\\Desktop\\client\\gp.png"// 传输的目标位置destFile := "D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\server\\gp-upload.png"// 临时记录文件tempFile := "D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\temp.txt"// 创建对应的file对象,连接起来file1, _ := os.Open(srcFile)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()fmt.Println("file1/2/3 文件连接建立完毕")// 1、读取temp.txtfile3.Seek(0, io.SeekStart)buf := make([]byte, 1024, 1024)n, _ := file3.Read(buf)// 2、转换成string - 数字。countStr := string(buf[:n])count, _ := strconv.ParseInt(countStr, 10, 64)fmt.Println("temp.txt中记录的值为:", count) // 5120// 3、设置读写的偏移量file1.Seek(count, io.SeekStart)file2.Seek(count, io.SeekStart)fmt.Println("file1/2 光标已经移动到了目标位置")// 4、开始读写(复制、上传)bufData := make([]byte, 1024, 1024)// 5、需要记录读取了多少个字节total := int(count)for {// 读取数据readNum, err := file1.Read(bufData)if err == io.EOF { // file1 读取完毕了fmt.Println("文件传输完毕了")file3.Close()os.Remove(tempFile)break}// 向目标文件中写入数据writeNum, err := file2.Write(bufData[:readNum])// 将写入数据放到 total中, 在这里total 就是传输的进度total = total + writeNum// temp.txt 存放临时记录数据file3.Seek(0, io.SeekStart) // 将光标重置到开头file3.WriteString(strconv.Itoa(total))}}
遍历文件夹
下去一定要自己实现
package mainimport ("fmt""log""os"
)// cd /d 文件夹路径
// tree /F , 查看当前文件夹下的所有文件// 遍历文件夹
// 1、读取当前文件夹下的所有文件
// 2、如果是文件夹,进入文件夹,继续读取里面的所有文件
// 3、设置一些结构化代码
func main() {dir := "D:\\Environment\\GoWorks\\src\\xuego"tree(dir, 0)
}// 日常调试测试常用fmt输出 、 工作中or项目中更多是log日志输出
func tree(dir string, level int) {// 编写层级tabString := "|--"for i := 0; i < level; i++ {tabString = "| " + tabString}// 获取目录 ReadDir, 返回目录信息[]DirEntry,多个文件信息fileInfos, err := os.ReadDir(dir)if err != nil {log.Println(err)}// 遍历出来所有文件之后,获取里面的单个文件for _, file := range fileInfos {// 文件夹中文件的全路径展示filename := dir + "\\" + file.Name()fmt.Println(tabString + file.Name())// 如果是文件夹,再次遍历if file.IsDir() {tree(filename, level+1)}}}
bufio
Go语言自带的IO操作包。bufio,使用这个包可以大幅提升文件的读写效率。
buf: 缓冲区.
io操作效率本身是还可以的,频繁访问本地磁盘文件(效率低)
所以说 bufio ,提供了一个缓冲区,读和写都先在缓冲区中,最后再一次性读取或者写入到文件里,降低访问本地磁盘的次数。
bufio写入
package mainimport ("bufio""fmt""log""os"
)// bufio 的应用
func main() {file, err := os.Open("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\demo01.go")if err != nil {log.Println(err)}defer file.Close()// 读取文件// 创建一个bufio包下的 reader对象。//bufioReader := bufio.NewReader(file)//buf := make([]byte, 1024)//n, err := bufioReader.Read(buf)//fmt.Println("读取到了多少个字节:", n)// 读取键盘的输入// 键盘的输入,实际上是流 os.StdininputReader := bufio.NewReader(os.Stdin)// delim 到哪里结束读取readString, _ := inputReader.ReadString('\n')fmt.Println("读取键盘输入的信息:", readString)}
bufio写出
package mainimport ("bufio""fmt""os"
)// 写入
func main() {file, _ := os.OpenFile("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\a.txt",os.O_RDWR|os.O_CREATE,os.ModePerm)defer file.Close()// bufiofileWrite := bufio.NewWriter(file)writeNum, _ := fileWrite.WriteString("kuangshen")fmt.Println("writeNum:", writeNum)// 发现并没有写出到文件,是留在了缓冲区,所以我们需要调用 flush 刷新缓冲区// 手动刷新进文件fileWrite.Flush()
}