golang基础小记(18)——文件操作:文件开关、简单的读写实例、设置文件读写位置、文件删除、文件名重命名

文件打开和关闭

os包中Open()函数能够以只读方式打开一个文件,函数返回*Fileerr。打开的文件可以通过调用Close()方法关闭。
Open()函数定义:

func Open(name string) (*File, error)

Open()函数接收文件路径,返回一个文件指针和可能的具体错误。
Close()方法定义:

func (file *File) Close() error

示例:

import (
	"fmt"
	"os"
)

func main() {
	file, err := os.Open("./main.go")
	if err != nil {
		fmt.Println("open file failed!, err:", err)
		return
	}
	// 关闭文件,配合defer能防止忘记关闭
	defer file.Close()
}

文件读取

Read()方法

定义:

func (f *File) Read(b []byte) (n int, err error)

Read()方法接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0io.EOF(需要导入io包)。
示例:

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

func main() {
	// 只读方式打开当前目录下的main.go文件
	file, err := os.Open("./main.go")
	if err != nil {
		fmt.Println("open file failed!, err:", err)
		return
	}
	defer file.Close()
	// 循环读取文件
	var content []byte
	var tmp = make([]byte, 128)
	for {
		n, err := file.Read(tmp)
		if err == io.EOF {
			fmt.Println("文件读完了")
			break
		}
		if err != nil {
			fmt.Println("read file failed, err:", err)
			return
		}
		content = append(content, tmp[:n]...)
	}
	fmt.Println(string(content))
}

bufio按行读取

需要导入bufio包。
按行读取示例:

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

func main() {
	file, err := os.Open("./main.go")
	if err != nil {
		fmt.Println("open file failed, err:", err)
		return
	}
	defer file.Close()
	// 新建一个缓冲区,把内容先放在缓冲区
	reader := bufio.NewReader(file)
	for {
		// 遇到'\n'则结束读取,读取内容包括'\n'
		line, err := reader.ReadString('\n') // 注意是字符
		if err == io.EOF {
			if len(line) != 0 {
				fmt.Println(line)
			}
			fmt.Println("文件读完了")
			break
		}
		if err != nil {
			fmt.Println("read file failed, err:", err)
			return
		}
		fmt.Print(line)
	}
}

示例中用到了bufio包中的一个函数和一个方法。
NewReader()函数格式:

func NewReader(rd io.Reader) *Reader

NewReader()函数会新建一个默认大小的缓冲区,把文件内容先放在缓冲区,返回该缓冲区指针。其参数是一个接口,当接收文件指针时,可以读取文件内容;当接收io.Stdin时,从标准输入生成读对象。

ReadString()方法格式:

func (b *Reader) ReadString(delim byte) (string, error)

ReadString()方法接收的是一个字符,每次读取到这个字符为止,包括该字符。所以当传入\n时,就可以实现一次读取一行。其返回值是读取的字符串和可能的具体错误。

ioutil一次性读取整个文件

需要导入io/ioutil包。
示例:

import (
	"fmt"
	"io/ioutil"
)

func main() {
	content, err := ioutil.ReadFile("./main.go")
	if err != nil {
		fmt.Println("read file failed, err:", err)
		return
	}
	fmt.Println(string(content))
}

ReadFile()函数格式:

func ReadFile(filename string) ([]byte, error)

ReadFile()函数接收文件路径,返回包含整个文件的字节切片和可能的具体错误。

文件写入

os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能。
格式:

func OpenFile(name string, flag int, perm FileMode) (*File, error)
  • name:文件路径
  • flag
const (
	// Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
	O_RDONLY int = syscall.O_RDONLY // open the file read-only.
	O_WRONLY int = syscall.O_WRONLY // open the file write-only.
	O_RDWR   int = syscall.O_RDWR   // open the file read-write.
	// The remaining values may be or'ed in to control behavior.
	O_APPEND int = syscall.O_APPEND // append data to the file when writing.
	O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
	O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist.
	O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
	O_TRUNC  int = syscall.O_TRUNC  // truncate regular writable file when opened.
)
  • perm:文件权限,一个八进制数。r(读)04,w(写)02,x(执行)01

Write和WriteString

直接将内容写入文件。

import (
	"fmt"
	"os"
)

func main() {
	file, err := os.OpenFile("t1.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println("open file failed, err:", err)
		return
	}
	defer file.Close()
	str := "hello 浙江\n"
	file.Write([]byte(str))      // 写入字节切片数据
	file.WriteString("hello 杭州") // 直接写入字符串数据
}

Write()方法格式:

func (f *File) Write(b []byte) (n int, err error)

Write()方法接收一个字节切片,返回值是字节切片长度和可能的具体错误。

WriteString()方法:

func (f *File) WriteString(s string) (n int, err error) {
	return f.Write([]byte(s))
}

可以看到WriteString()函数就是将传入的字符串转换成字节切片,再调用Write()方法,返回值相同。

bufio.NewWriter

将数据先写入缓冲区,写完后一次性将缓冲区中的内容写入文件。

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

func main() {
	file, err := os.OpenFile("t1.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println("open file failed, err:", err)
		return
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	for i := 0; i < 10; i++ {
		writer.WriteString("hello中国" + strconv.Itoa(i) + "\n") // 将数据先写入缓存
	}
	writer.Flush() // 将缓存中的内容写入文件
}

NewWriter()函数格式:

func NewWriter(w io.Writer) *Writer

NewWriter()函数会新建一个默认大小的缓冲区,返回该缓冲区指针。

WriteString()方法格式:

func (b *Writer) WriteString(s string) (int, error)

WriteString()方法接收一个字符串,返回已经写入的字节数,如果写入字节数< len(s),返回具体的错误。

Flush()方法:将缓冲区的内容写入文件。

ioutil.WriteFile

将内容直接写入文件。

func main() {
	str := `
	hello 中国
	hello 浙江
	hello 杭州`
	err := ioutil.WriteFile("t1.txt", []byte(str), 0666)
	if err != nil {
		fmt.Println("write file failed, err:", err)
		return
	}
}

WriteFile()函数格式:

func WriteFile(filename string, data []byte, perm os.FileMode) error

其它文件操作方法/函数补充

Seek()方法设置文件读写位置

格式:

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

Seek()方法能设置下一次读/写的位置。offset为相对偏移量,而whence决定相对位置:0为相对文件开头,1为相对当前位置,2为相对文件结尾。它返回新的偏移量(相对开头)和可能的错误。

Rename()函数重命名文件

注意:使用前需要关闭文件。
格式:

func Rename(oldpath, newpath string) error

示例:

os.Rename("./t1.txt", "./t2.txt")

示例中将文件名t1.txt改为t2.txt,重命名的过程中利用newpath还可以移动文件位置。

Remove()函数删除文件/目录

注意:使用前需要关闭文件。
格式:

func Remove(name string) error

Remove()函数能删除name指定的文件或目录。如果出错,会返回*PathError底层类型的错误。
更多函数/方法可查中文版包文档
参考

猜你喜欢

转载自blog.csdn.net/m0_37710023/article/details/107844665