首页 > 其他分享 >golang IO流

golang IO流

时间:2024-07-16 10:56:11浏览次数:10  
标签:文件 IO io fmt golang file os bufio

golang IO流

file一些操作os包下

  1. FileInfo : 获取文件信息
  2. Reader : 读
  3. Write:写
  4. 文件复制
  5. mkdir
  6. create
  7. 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 main

import (
   "fmt"
   "io"
   "os"
)

func main() {
   // 读取文件
   file, _ := os.OpenFile("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\a.txt",
      os.O_RDWR, os.ModePerm)
   // defer close
   defer file.Close()

   // 测试seek
   // 相对开始位置。io.SeekStart
   // 相对于文件末尾, io.SeekEnd
   file.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 main

import (
   "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.txt
   file3.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 main

import (
   "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 main

import (
   "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.Stdin
   inputReader := bufio.NewReader(os.Stdin)
   // delim 到哪里结束读取
   readString, _ := inputReader.ReadString('\n')
   fmt.Println("读取键盘输入的信息:", readString)

}

bufio写出

package main

import (
   "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()

   // bufio
   fileWrite := bufio.NewWriter(file)
   writeNum, _ := fileWrite.WriteString("kuangshen")
   fmt.Println("writeNum:", writeNum)
   // 发现并没有写出到文件,是留在了缓冲区,所以我们需要调用 flush 刷新缓冲区
   // 手动刷新进文件
   fileWrite.Flush()
}

标签:文件,IO,io,fmt,golang,file,os,bufio
From: https://blog.csdn.net/m0_63573177/article/details/140446131

相关文章

  • Python安装出现严重错误的解决方法_0x80070643-( A newer version of the Python laun
    每次在装软件配置环境的时候,总会遇到别人碰不到的各种问题,人都麻了。最后我还是自己尝试这解决了,只是建议,虽然说不知道是否以后还会问题,但是可以成功安装,配置环境并运行。(本人是win11)首先解释一下pythonlauncher是什么资料解释:PythonLauncher是Python官方提供的一个工具,......
  • CF1988C Increasing Sequence with Fixed OR Solution
    题意简述如下:给定一个正整数\(n\),请构造一个正整数序列使其满足以下条件并尽可能长:这个序列中每个数都大于等于\(1\)且小于等于\(n\);这个序列是单调递增的;这个序列中任意两个相邻的数按位或的结果都为\(n\)。通过手玩或者写个最长上升子序列可以发现,我们记这个数在二进制......
  • 安装软件Docker Desktop Installer.exe后导致的AMD显卡掉驱动,提示:The version of AMD
    打开AMDRadeonSoftware时总是弹出“TheversionofAMDRadeonSoftwareyouhavelaunchedisnotcompatiblewithyourcurrentlyinstalledAMDgraphicsdriver."提示框,如图所示:TheversionofAMDRadeonSoftwareyouhavelaunchedisnotcompatiblewithyourcurr......
  • Java 基础IO
    目录如何从数据传输方式理解IO流?#如何从数据操作上理解IO流?#JavaIO设计上使用了什么设计模式?如何从数据传输方式理解IO流?从数据传输方式或者说是运输方式角度看,可以将IO类分为:字节流,字节流读取单个字节,字符流读取单个字符(一个字符根据编码的不同,对应的字节也......
  • 木舟0基础学习Java的第十八天(IO流,字节流,字符流,缓冲)
    IO流正常使用流程:1.抛异常 2.资源读写 3.关闭资源(从后往前关)字节流:(拷贝推荐使用)开发中一般不会抛出异常用try{}catch(){}也不推荐字节流读中文FileInputStream:读FileInputStreamfs=newFileInputStream("e:/b.txt");//11111111为-1的补......
  • 木舟0基础学习Java的第十七天(File类使用,IO流)
     File类(路径):文件路径文件夹路径路径:1.绝对路径:固定的路径从盘符开始2.相对路径:相对于某个位置指当前项目下创建功能:Filef=newFile("e:/a.txt");try{booleanb1=f.createNewFile();//新建文件System.out.println(b1);......
  • optional
    作用:用来包装一个可能存在也可能不存在的值当存在时我们可以选择返回其中内容,不存在时返回空;代码示例:#include<iostream>#include<optional>#include<string>#include<fstream>std::optional<std::string>ReadFileAsString(conststd::string&filepath){std::i......
  • Regularized Stochastic Learning and Online Optimization
    目录概符号说明MotivationFOBOS(Forward-BackwardSplitting)RDA(RegularizedDualAveraging)FTRL-Proximal(FollowTheRegularizedLeader)FOBOS,RDA,FTRL-Proximal的统一表示[1]DuchiJ.andSingerY.EfficientLearningusingForward-BackwardSplitting.NeurIP......
  • VINS-Fusion源码逐行解析:updateLatestStates()函数与slideWindow()
    初始化并优化位姿后,接下来做的事是将这些位姿更新给上一帧,我们来看下updateLatestStates()源码:voidEstimator::updateLatestStates(){//锁定mPropagate,确保对最新状态的更新是线程安全的mPropagate.lock();//更新最新的时间戳,等于当前帧的时间戳加上时间延......
  • 使用预训练模型(yolov8、MobileNetV2、ResNet50)与Gradio构建图像目标检测Web应用
    简介:  利用gradio设计一个web运用,实现图片主体物的识别。  1)用户可以通过网页提交一张图片。  2)web应用将输出这张图片中主体物的名称(中英文都可以)。  3)可以使用预训练的模型。利用预训练实现对物体识别准备工作在开始之前,请确保你的环境中已安装了以下依赖......