• go语言中的读写操作以及文件的复制


    目录

    一、文件读写

    1.读取文件中的数据:

     2.写出数据到本地文件:

    二、文件复制

    1、方法一:io包下的Read()和Write()方法实现

    2、方法二:io包下的Copy()方法实现

    3、方法三:ioutil包


    一、文件读写

    file类是在os包中的,封装了底层的文件描述符和相关信息,同时封装了Read和Write的实现。

    1. func (f *File) Read(b []byte) (n int, err error)
    2. //Read方法从f中读取最多len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。文件终止标志是读取0个字节且返回值err为io.EOF。
    3. func (f *File) ReadAt(b []byte, off int64) (n int, err error)
    4. //ReadAt从指定的位置(相对于文件开始位置)读取len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。当n
    5. func (f *File) Write(b []byte) (n int, err error)
    6. //Write向文件中写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
    7. func (f *File) WriteString(s string) (ret int, err error)
    8. //WriteString类似Write,但接受一个字符串参数。
    9. func (f *File) WriteAt(b []byte, off int64) (n int, err error)
    10. //WriteAt在指定的位置(相对于文件开始位置)写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
    11. func (f *File) Seek(offset int64, whence int) (ret int64, err error)
    12. //Seek设置下一次读/写的位置。offset为相对偏移量,而whence决定相对位置:0为相对文件开头,1为相对当前位置,2为相对文件结尾。它返回新的偏移量(相对开头)和可能的错误。
    13. func (f *File) Sync() (err error)
    14. //Sync递交文件的当前内容进行稳定的存储。一般来说,这表示将文件系统的最近写入的数据在内存中的拷贝刷新到硬盘中稳定保存。

    1.读取文件中的数据:

    读取数据:
       Reader接口:
          Read(p []byte)(n int, error)

    示例代码:

    1. package main
    2. import (
    3. "fmt"
    4. "io"
    5. "os"
    6. )
    7. func main() {
    8. //读取本地aa.txt文件中的数据
    9. //step1:打开文件
    10. fileName := "abcd.txt"
    11. file,err := os.Open(fileName)
    12. if err != nil{
    13. fmt.Println("err:",err)
    14. return
    15. }
    16. //step3:关闭文件
    17. defer file.Close()
    18. //step2:读取数据
    19. bs := make([]byte,4,4)
    20. /*
    21. //第一次读取
    22. n,err :=file.Read(bs)
    23. fmt.Println(err) //
    24. fmt.Println(n) //4
    25. fmt.Println(bs) //[97 98 99 100]
    26. fmt.Println(string(bs)) //abcd
    27. //第二次读取
    28. n,err = file.Read(bs)
    29. fmt.Println(err)//
    30. fmt.Println(n)//4
    31. fmt.Println(bs) //[101 102 103 104]
    32. fmt.Println(string(bs)) //efgh
    33. //第三次读取
    34. n,err = file.Read(bs)
    35. fmt.Println(err) //
    36. fmt.Println(n) //2
    37. fmt.Println(bs) //[105 106 103 104]
    38. fmt.Println(string(bs)) //ijgh
    39. //第四次读取
    40. n,err = file.Read(bs)
    41. fmt.Println(err) //EOF
    42. fmt.Println(n) //0
    43. */
    44. n := -1
    45. for{
    46. n,err = file.Read(bs)
    47. if n == 0 || err == io.EOF{
    48. fmt.Println("读取到了文件的末尾,结束读取操作。。")
    49. break
    50. }
    51. fmt.Println(string(bs[:n]))
    52. }
    53. }

     2.写出数据到本地文件:

    1. package main
    2. import (
    3. "os"
    4. "fmt"
    5. "log"
    6. )
    7. func main() {
    8. /*
    9. 写出数据:
    10. */
    11. fileName := "/Users/ruby/Documents/pro/a/ab.txt"
    12. //step1:打开文件
    13. //step2:写出数据
    14. //step3:关闭文件
    15. //file,err := os.Open(fileName)
    16. file,err := os.OpenFile(fileName,os.O_CREATE|os.O_WRONLY|os.O_APPEND,os.ModePerm)
    17. if err != nil{
    18. fmt.Println(err)
    19. return
    20. }
    21. defer file.Close()
    22. //写出数据
    23. //bs :=[]byte{65,66,67,68,69,70}//A,B,C,D,E,F
    24. bs :=[] byte{97,98,99,100} //a,b,c,d
    25. //n,err := file.Write(bs)
    26. n,err := file.Write(bs[:2])
    27. fmt.Println(n)
    28. HandleErr(err)
    29. file.WriteString("\n")
    30. //直接写出字符串
    31. n,err = file.WriteString("HelloWorld")
    32. fmt.Println(n)
    33. HandleErr(err)
    34. file.WriteString("\n")
    35. n,err =file.Write([]byte("today"))
    36. fmt.Println(n)
    37. HandleErr(err)
    38. }
    39. func HandleErr(err error){
    40. if err != nil{
    41. log.Fatal(err)
    42. }
    43. }

    二、文件复制

    在io包中主要是操作流的一些方法,今天主要学习一下copy。就是把一个文件复制到另一个目录下。它的原理就是通过程序,从源文件读取文件中的数据,在写出到目标文件里。

    1、方法一:io包下的Read()和Write()方法实现

    我们可以通过io包下的Read()和Write()方法,边读边写,就能够实现文件的复制。这个方法是按块读取文件,块的大小也会影响到程序的性能。

    1. /*
    2. 该函数的功能:实现文件的拷贝,返回值是拷贝的总数量(字节),错误
    3. */
    4. func copyFile1(srcFile,destFile string)(int,error){
    5. file1,err:=os.Open(srcFile)
    6. if err != nil{
    7. return 0,err
    8. }
    9. file2,err:=os.OpenFile(destFile,os.O_WRONLY|os.O_CREATE,os.ModePerm)
    10. if err !=nil{
    11. return 0,err
    12. }
    13. defer file1.Close()
    14. defer file2.Close()
    15. //拷贝数据
    16. bs := make([]byte,1024,1024)
    17. n :=-1//读取的数据量
    18. total := 0
    19. for {
    20. n,err = file1.Read(bs)
    21. if err == io.EOF || n == 0{
    22. fmt.Println("拷贝完毕。。")
    23. break
    24. }else if err !=nil{
    25. fmt.Println("报错了。。。")
    26. return total,err
    27. }
    28. total += n
    29. file2.Write(bs[:n])
    30. }
    31. return total,nil
    32. }

    2、方法二:io包下的Copy()方法实现

    我们也可以直接使用io包下的Copy()方法。

    示例代码如下:

    1. func copyFile2(srcFile, destFile string)(int64,error){
    2. file1,err:=os.Open(srcFile)
    3. if err != nil{
    4. return 0,err
    5. }
    6. file2,err:=os.OpenFile(destFile,os.O_WRONLY|os.O_CREATE,os.ModePerm)
    7. if err !=nil{
    8. return 0,err
    9. }
    10. defer file1.Close()
    11. defer file2.Close()
    12. return io.Copy(file2,file1)
    13. }

    3、方法三:ioutil包

    使用ioutil包中的 ioutil.WriteFile()和 ioutil.ReadFile(),但由于使用一次性读取文件,再一次性写入文件的方式,所以该方法不适用于大文件,容易内存溢出。

    示例代码:

    1. func copyFile3(srcFile, destFile string)(int,error){
    2. input, err := ioutil.ReadFile(srcFile)
    3. if err != nil {
    4. fmt.Println(err)
    5. return 0,err
    6. }
    7. err = ioutil.WriteFile(destFile, input, 0644)
    8. if err != nil {
    9. fmt.Println("操作失败:", destFile)
    10. fmt.Println(err)
    11. return 0,err
    12. }
    13. return len(input),nil
    14. }

    这3种方式,在性能上,不管是还是io.Copy()还是ioutil包,性能都是还不错的。

  • 相关阅读:
    position left设置居中,除了auto以外,还有什么方式
    pytorch 入门 (四)案例二:人脸表情识别-VGG16实现
    单多行文本溢出显示省略号
    SpringCloud Config 分布式服务配置
    【Linux】环境变量
    输入一批数,找中位数
    猿创征文 |【gin-vue-admin】后端结构设计和基本工作原理
    python中的类型提示(定义函数时加入箭头->)
    HTML笔记-狂神
    推荐系统笔记(十四):极简图对比学习方法SimGCL
  • 原文地址:https://blog.csdn.net/m0_51530927/article/details/125886621