GO基础进阶篇 (六)、I/O流

os包

os 包是 Go 语言的一个内置包,用于提供与操作系统进行交互的功能。该包包含了一些用于处理文件、目录以及执行系统命令等操作的函数。

1.获取文件信息

package main

import (
	"fmt"
	"os"
)

func main() {
	//获取文件信息
	fileInfo, err := os.Stat("ten/a.txt")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(fileInfo.Name())
	fmt.Println(fileInfo.IsDir())
	fmt.Println(fileInfo.Size())
	fmt.Println(fileInfo.Mode())
	fmt.Println(fileInfo.ModTime())

	//通过反射获取更详细的信息
	fmt.Println(fileInfo.Sys())

	//a.txt
	//false
	//18
	//2023-12-19 11:10:30.521995858 +0800 CST
	//-rw-r--r--
	//&{16777232 33188 1 28010539 501 20 0 [0 0 0 0] {1702955432 197963398} {1702955430 521995858} {1702955430 521995858} {1702955424 572641617} 18 8 4096 0 0 0 [0 0]}
}

2.创建删除文件、文件夹

package main

import (
	"fmt"
	"os"
)

func main() {
	//获取文件信息
	fileInfo, err := os.Stat("ten/a.txt")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(fileInfo.Name())
	fmt.Println(fileInfo.IsDir())
	fmt.Println(fileInfo.Size())
	fmt.Println(fileInfo.Mode())
	fmt.Println(fileInfo.ModTime())

	//通过反射获取更详细的信息
	fmt.Println(fileInfo.Sys())

	//a.txt
	//false
	//18
	//2023-12-19 11:10:30.521995858 +0800 CST
	//-rw-r--r--
	//&{16777232 33188 1 28010539 501 20 0 [0 0 0 0] {1702955432 197963398} {1702955430 521995858} {1702955430 521995858} {1702955424 572641617} 18 8 4096 0 0 0 [0 0]}

	//创建单层文件夹
	err1 := os.Mkdir("ten/testDir", os.ModePerm)
	if err1 != nil {
		fmt.Println(err1)
	}
	fmt.Println("创建完毕")

	//创建多层级文件夹
	err2 := os.MkdirAll("ten/testDir/a/b/c", os.ModePerm)
	if err2 != nil {
		fmt.Println(err2)
	}
	fmt.Println("创建完毕")

	//删除文件夹
	err3 := os.Remove("ten/testDir")
	if err3 != nil {
		fmt.Println(err3)
	}
	fmt.Println("删除完毕")

	//删除多层级文件夹
	err4 := os.RemoveAll("ten/testDir")
	if err4 != nil {
		fmt.Println(err4)
	}
	fmt.Println("删除完毕")

	//创建文件,默认覆盖创建
	file, err5 := os.Create("ten/b.text")
	fmt.Println(file)
	fmt.Println(err5)
	//删除文件
	os.Remove("ten/b.text")
}

3.IO读

package main

import (
	"fmt"
	"os"
)

func main() {
	//打开文件 建立连接open
	//file, err := os.Open("ten/a.txt")
	//使用权限打开文件,路径,权限,模式
	file, err := os.OpenFile("ten/a.txt", os.O_RDONLY, os.ModePerm)

	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(file.Name())
	defer file.Close()

	bs := make([]byte, 2, 1024)
	//读取a.text内容
	n, _ := file.Read(bs)
	fmt.Println(n)
	fmt.Println(string(bs))
}

4.IO写


import (
	"fmt"
	"os"
)

func main() {
	//打开文件 建立连接open
	//file, err := os.Open("ten/a.txt")
	//使用权限打开文件,路径,权限,模式
	file, err := os.OpenFile("ten/a.txt",
		os.O_RDONLY|os.O_WRONLY|os.O_APPEND, os.ModePerm)

	if err != nil {
		fmt.Println(1, err)
		return
	}
	defer file.Close()

	//业务代码
	bs := []byte{65, 66, 67, 68, 69}
	//没用|os.O_APPEND模式查查询   覆盖写入a.text内容,且只覆盖了前5个字符,用了的话就是追加
	fmt.Println(file.Name())
	n, err1 := file.Write(bs)
	//n2, err2 := file.WriteString("ssssssss")
 
	if err1 != nil {
		fmt.Println(2, err1)
		return
	}
	fmt.Println(n)

}

5.Seeker接口

在Go语言中,file.Seek() 函数用于设置文件指针的位置。它的签名如下:

func (f *File) Seek(offset int64, whence int) (ret int64, err error)

其中:

  • offset 表示相对于 whence 参数的偏移量,可以为正数、负数或零。
  • whence 表示相对位置的基准点,它可以取以下三个值:
    • io.SeekStart:相对文件开始位置。
    • io.SeekCurrent:相对当前文件指针位置。
    • io.SeekEnd:相对文件末尾。

6.断点续传功能

通过临时文件来存储文件写入时的光标位置,出现异常时从光标位置恢复上传。

package main

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

func main() {
	//断点续传
	srcFile := "demo/preview.jpg"
	destFile := "demo/preview1.jpg"
	tempFile := "demo/temp.txt"

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

	file3.Seek(0, io.SeekStart)

	buf := make([]byte, 1024, 1024)
	n, _ := file3.Read(buf)
	countStr := string(buf[:n]) //:n  从0-n的数据
	fmt.Println("countStr", countStr)

	count, _ := strconv.ParseInt(countStr, 10, 64)

	//seek
	file1.Seek(count, io.SeekStart)
	file2.Seek(count, io.SeekStart)

	bufData := make([]byte, 1024, 1024)
	total := int(count)

	for {
		readNum, err := file1.Read(bufData)
		fmt.Println(readNum)
		if err == io.EOF {
			fmt.Println("读取完毕")
			file3.Close()
			break
		}
		writeNum, err := file2.Write(bufData[:readNum])

		total = total + writeNum
		//将传输进度存储到临时文件中
		file3.Seek(0, io.SeekStart)
		file3.WriteString(strconv.Itoa(total))
		
		//模拟panic,触发续传
		//if total > 9000 {
		//	panic("断电了")
		//}
	}
}

7.bufio包

在Go语言中,bufio 包提供了带缓冲的 I/O 操作,可以用于提高读取和写入的性能。bufio 包主要包含了两种类型的结构:ReaderWriter

bufio.Reader

bufio.Reader 提供了带缓冲的读取操作。通过它,你可以从一个 io.Reader 实例中读取数据,并且可以使用缓冲来减少对底层数据源的直接读取次数,提高性能。以下是一些 bufio.Reader 的常用方法:

  • NewReader(rd io.Reader) *Reader: 创建一个新的 Reader 对象,使用给定的 io.Reader 作为底层数据源。

  • func (b *Reader) Read(p []byte) (n int, err error): 从底层数据源读取数据到缓冲,然后从缓冲中读取数据到 p 中。

  • func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error): 读取一行数据,返回行数据和一个标志,指示是否读取的是行的前缀。

  • func (b *Reader) ReadString(delim byte) (string, error): 读取直到遇到指定的分隔符 delim 的字符串。

bufio.Writer

bufio.Writer 提供了带缓冲的写入操作。通过它,你可以将数据写入到一个 io.Writer 实例,并且可以使用缓冲来减少对底层数据源的直接写入次数,提高性能。以下是一些 bufio.Writer 的常用方法:

  • NewWriter(wr io.Writer) *Writer: 创建一个新的 Writer 对象,使用给定的 io.Writer 作为底层数据源。

  • func (b *Writer) Write(p []byte) (n int, err error): 将数据写入到缓冲,然后再将缓冲中的数据写入底层数据源。

  • func (b *Writer) WriteString(s string) (n int, err error): 将字符串写入到缓冲,然后再将缓冲中的数据写入底层数据源。

  • func (b *Writer) Flush() error: 将缓冲中的数据写入底层数据源。

以下是一个简单的示例,演示如何使用 bufio.Readerbufio.Writer 进行文件的读写操作:

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	// 使用 bufio.Reader 读取文件内容
	file, err := os.Open("example.txt")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer file.Close()

	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			break
		}
		fmt.Print(line)
	}

	// 使用 bufio.Writer 写入文件内容
	outputFile, err := os.Create("output.txt")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer outputFile.Close()

	writer := bufio.NewWriter(outputFile)
	_, err = writer.WriteString("Hello, bufio!\n")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// 刷新缓冲,确保数据写入文件
	err = writer.Flush()
	if err != nil {
		fmt.Println("Error:", err)
	}
}

在这个例子中,bufio.Reader 用于逐行读取文件内容,而 bufio.Writer 用于向文件写入一行字符串。

你可能感兴趣的:(GO语言从基础到应用,golang,开发语言,后端)