Golang 之 文件

Posted newbase

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang 之 文件相关的知识,希望对你有一定的参考价值。

好久之前学得了,用到时发现全忘了,记录一下

打开文件 + 关闭文件

os.Open

os.Open()函数能够打开一个文件,返回一个*File和一个err*File为即文件对象(文件指针、文件句柄),file是在os包中的,封装了底层的文件描述符和相关信息,同时封装了Read和Write等的实现。

对得到的文件实例调用close()方法能够关闭文件。

其定义为:

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

实例:

func main() {
	// 只读方式打开当前目录下的main.go文件
	file, err := os.Open("./main.go")
	if err != nil {
		fmt.Println("open file failed!, err:", err)
		return
	}
	// 关闭文件
	defer file.Close()
}

os.OpenFile

第二种打开文件的方法,使用os.OpenFile函数,该能够以指定模式flag打开文件,从而实现文件写入相关功能(见下文),其定义为:

func OpenFile(name string, flag int, perm FileMode) (*File, error) 

name:要打开的文件名

flag:打开文件的模式。 模式有以下几种:

模式 含义
os.O_WRONLY 只写
os.O_CREATE 创建文件
os.O_RDONLY 只读
os.O_RDWR 读写
os.O_TRUNC 清空
os.O_APPEND 追加

perm:文件权限(linux系统下生效),一个八进制数。r(读)04,w(写)02,x(执行)01。

实例:

package main

import (
	"fmt"
	"os" 
)

func main() {
    
	// 以 只写模式 打开或创建并打开 文件 d:/abc.txt
	filePath := "d:/abc.txt"
	file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("open file err=%v
", err)
		return 
	}
   
	// 函数执行结束关闭file句柄
	defer file.Close()
    
    ...执行写入操作,详见下文...
    
}

读取文件

file.Read()

用Read方法定义如下:

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

它接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0io.EOF。 举个例子:

func main() {
    
	// 只读方式打开当前目录下的main.go文件
	file, err := os.Open("./main.go")
	if err != nil {
		fmt.Println("open file failed!, err:", err)
		return
	}
    
	defer file.Close()
    
	// 使用Read方法读取数据
	var tmp = make([]byte, 128)
    
	n, err := file.Read(tmp)
   
	if err == io.EOF {
		fmt.Println("文件读完了")
		return
	}
	if err != nil {
		fmt.Println("read file failed, err:", err)
		return
	}
    
	fmt.Printf("读取了%d字节数据
", n)
	fmt.Println(string(tmp[:n]))
}

循环读取

使用for循环读取文件中的所有数据。

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是在file的基础上封装了一层API,支持更多的功能,下面实例为按行读取。

package main

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

// 按行读取
func main() {
    
	file, err := os.Open("./xx.txt")
	if err != nil {
		fmt.Println("open file failed, err:", err)
		return
	}
    
	defer file.Close()
    
	reader := bufio.NewReader(file)
    
	for {
		line, err := reader.ReadString(‘
‘)  // 读取到换行符就换行读取
        
		// 读取到文件末尾但最后一行没读完,输出最后一行
        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)
	}
}

ioutil 读取整个文件

io/ioutil包的ReadFile方法能够读取完整的文件,只需要将文件名作为参数传入。

package main

import (
	"fmt"
	"io/ioutil"
)

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

写入文件

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

打开文件的模式:

模式 含义
os.O_WRONLY 只写
os.O_CREATE 创建文件
os.O_RDONLY 只读
os.O_RDWR 读写
os.O_TRUNC 清空
os.O_APPEND 追加

Write 和 WriteString(直接写入)

func main() {
    
    // 清空原文件,以读写模式打开文件
	file, err := os.OpenFile("xx.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 侠奢"
    
    // 直接写入字节切片数据
	file.Write([]byte(str))
    // 直接写入字符串数据
	file.WriteString(str)    
}

bufio.NewWriter(带缓存)

将数据先写入缓存,后写入文件,适用于较大的文件

func main() {
    
    // 清空原文件,以读写模式打开文件
	file, err := os.OpenFile("xx.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)
    
    // 在文件里写10个 hello 侠奢
	for i := 0; i < 10; i++ {
		writer.WriteString("hello 侠奢
")   // 将数据(字符串)先写入缓存,
都是换行
	}
    
	writer.Flush()   // 将缓存中的内容写入文件※
}

ioutil.WriteFile

函数定义:

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

不打开文件(OpenFile),直接写入

import (
	"fmt"
	"io/ioutil"
)

func main() {
    
	str := "hello 侠奢"
    
    // 直接写入
	err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
	if err != nil {
		fmt.Println("write file failed, err:", err)
		return
	}
}

判断文件是否存在

一般采用os.Stat

其定义为:

func Stat(name string) (FileInfo, error)

判断文件是否存在主要看error的返回值:

  • 如果返回nil说明文件存在
  • 返回错误os.isNotExist判断为ture,说明文件不存在
  • 返回其他错位类型,则不能确定文件是否存在
// 输入文件地址,判断文件是否存在
func PathExists(path string) (bool, error) {
   _, err := os.Stat(path)
   if err == nil {
      return true, nil
   }
   if os.IsExist(err) {
      return false, nil
   }
   return false, err
}

文件信息读取

package main

import (
	"fmt"
	"os"
)

func main() {
	/*
		fileInfo:文件信息
			interface
				Name(),文件名
				Size(),文件大小,字节为单位
				IsDir(),是否是目录
				ModTime(),修改时间
				Mode(),权限

	*/

	// 定义
	fileInfo,err :=  os.Stat("D:/GoWork/src/awesomeProject/xiashe.txt")
	if err != nil{
		fmt.Println("err :",err)
		return
	}

	// 接口类型
	fmt.Printf("%T
",fileInfo)
	// 文件名
	fmt.Println(fileInfo.Name())
	// 文件大小
	fmt.Println(fileInfo.Size())
	// 是否是目录
	fmt.Println(fileInfo.IsDir()) // IsDirectory
	// 修改时间
	fmt.Println(fileInfo.ModTime())
	// 权限
	fmt.Println(fileInfo.Mode()) // -rw-r--r--
}

返回结果:

技术图片

以上是关于Golang 之 文件的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 - Golang 实现简单的 Web 服务器

代码片段 - Golang 实现集合操作

json [Golang] golang #golang #snippets中有用的片段

走进 Golang 之编译器原理

golang之调用C语言代码

Golang之WebAssembly篇