文件IO操作

文件

简介

在golang中,os包下有File的结构体,封装这对文件的操作。
在这里插入图片描述

文件操作常用方法

打开和关闭

在这里插入图片描述

在这里插入图片描述
案例演示:

package main

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

func main(){
    // 打开文件
	file, err := os.Open("d:/test.txt")
	if err != nil {
		panic(err)
	}
	fmt.Println("打开文件")
	
	//按字节读取
	bs := make([] byte,3)
	for {
		_, err = file.Read(bs)
		if err == io.EOF { break}
		fmt.Print(string(bs))
	}
    //关闭文件
	errclose := file.Close()
	if errclose != nil {
		panic(errclose)
	}
	fmt.Println()
    fmt.Println("关闭文件")
}

test.txt内容如下

hello world 你好小明

在这里插入图片描述

内容读取

常见的读取内容有以下三种方式

package main
 
import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)
 
func main() {
	//1、一次性读取文件内容,还有一个 ReadAll的函数,也能读取
	// ReadFile将文件打开和关闭封装在一起,所以最后不用手动关闭
	data, err := ioutil.ReadFile("./util/file.go")
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(data))
 
	//2、bufio包下缓冲区的读取
	file, err := os.Open("d:/test.txt")   //打开
	if err != nil { fmt.Println(err); return  }
	defer file.Close() //关闭
 
	line := bufio.NewReader(file)
	for {
		content, _, err := line.ReadLine()
		if err == io.EOF { break }
		fmt.Println(string(content))
	}
 
	//3、按照字节数读取
	file,err= os.Open("./util/file.go")
	if err!=nil{ fmt.Println(err); return }
	defer file.Close()
	//读取数据
	bs := make([] byte,4)
	for {
		_, err = file.Read(bs)
		if err == io.EOF { break}
		fmt.Print(string(bs))
	}
}

文件内容有中文,第三种按字节读取会有问题,推荐使用第二种,带缓冲区的读取。
在这里插入图片描述
将test.txt内容修改如下

hello world 
你好
小明

案例演示

package main

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

func main() {

	// 打开文件
	file, err := os.Open("d:/test.txt")
	if err != nil {
		panic(err)
	}
    defer file.Close()
    // 缓冲区默认4096字节
	reader := bufio.NewReader(file)
	for {
		content, _, err := reader.ReadLine()
		if err == io.EOF { break }//文件末尾
		fmt.Println(string(content))
	}
}

在这里插入图片描述
使用ReadString读取
在这里插入图片描述

// 打开文件
	file, err := os.Open("d:/test.txt")
	if err != nil {
		panic(err)
	}
    defer file.Close()
    // 缓冲区默认4096字节
	reader := bufio.NewReader(file)

	for {
		readString, err := reader.ReadString('\n')
		if err == io.EOF { break }//文件末尾
		fmt.Println(readString)
	}

注意: 如果发现输出的内容少了最后一行,那是因为最后一行少了换行符,只要回车加一空行就行。
也可以使用如下方法避免少一行的问题
改进方法一

// 打开文件
	file, err := os.Open("d:/test.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

文件写入

简单写入
文件写入涉及到的方法有os.OpenFile以及io.WriteString

在这里插入图片描述
其中文件模式

const (
    O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
    O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
    O_RDWR   int = syscall.O_RDWR   // 读写模式打开文件
    O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
    O_CREATE int = syscall.O_CREAT  // 如果不存在将创建一个新文件
    O_EXCL   int = syscall.O_EXCL   // 和O_CREATE配合使用,文件必须不存在
    O_SYNC   int = syscall.O_SYNC   // 打开文件用于同步I/O
    O_TRUNC  int = syscall.O_TRUNC  // 如果可能,打开时清空文件
)

FileMode如下图
在这里插入图片描述
FileMode只在Linux和UNIX系统下有效,,windows下无效。

在bufio包下有带缓冲区写入的方法(推荐使用)
在这里插入图片描述

案例一: 创建新文件,并写入"hello 小明"

    filePath := "d:/w1.txt"
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		panic(err)
	}
	defer file.Close()
    str := "hello 小明"
	writer := bufio.NewWriter(file)
	writer.WriteString(str)

	// writer先写入到缓存,最后需要刷新缓存到文件
	writer.Flush()

案例二: 打开一个存在的文件,覆盖里面的内容,写入5句 “hello world”

    filePath := "d:/w1.txt"
	//os.O_WRONLY 写模式,os.O_TRUNC打开会清空文件
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC, 0666)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	str := "hello world\r\n"
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++{
		writer.WriteString(str)
	}
	// writer先写入到缓存,最后需要刷新缓存到文件
	writer.Flush()

案例三: 打开一个文件,在原文件基础上追加内容 “星期一”

filePath := "d:/w1.txt"
	file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_APPEND, 0666)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	str := "星期一"
	writer := bufio.NewWriter(file)
	writer.WriteString(str)
	// writer先写入到缓存,最后需要刷新缓存到文件
	writer.Flush()

案例四: 打开一个文件,将原文件内容输出到终端,并追加5句"北京 北京"

filePath := "d:/w1.txt"
	//os.O_RDWR 读写模式,os.O_APPEND 追加内容
	file, err := os.OpenFile(filePath, os.O_RDWR|os.O_APPEND, 0666)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	//先读取原内容,显示在终端
	/* 此方法,可能会造成最后一行显示不出
	reader := bufio.NewReader(file)
	for{
		str, err := reader.ReadString('\n')
		if err == io.EOF {
			break;
		}
		fmt.Print(str)
	}*/
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

	str := "北京 北京\r\n"
	writer := bufio.NewWriter(file)
	for i := 0; i < 5; i++{
		writer.WriteString(str)
	}
	// writer先写入到缓存,最后需要刷新缓存到文件
	writer.Flush()

案例五: 将A文件内容写入到B文件

fileSource := "d:/sour.txt"
	fileDest := "d:/dest.txt"
	//读取原文件
	data, err := ioutil.ReadFile(fileSource)
	if err != nil {
		panic(err)
	}
	//写入内容
	errWrite := ioutil.WriteFile(fileDest, data, 0666)
	if errWrite != nil {
		panic(errWrite)
	}

注意: 在写入之前会 清空B文件内容

判断文件/文件夹是否存在

golang判断文件或文件夹是否存在的方法为使用os.Stat()
在这里插入图片描述
1)如果返回的错误为nil说明文件或文件夹存在
2)如果返回的错误类型使用 os. IsNotExist()判断为true,说明文件或文件夹不存在
3)如果返回的错误为其它类型,则不确定是否存在
由以上三点写一个方法判断

func PathExists(path string) (bool,error){
	_, err := os.Stat(path)
	if err == nil {//文件存在
		return true,nil
	}
	if os.IsNotExist(err){//文件不存在
		return false,nil
	}
	return false,err
}

使用

    path := "d:/"
	exists, err := PathExists(path)
	if err == nil {
		if exists {
			fmt.Println("文件存在")
		} else {
			fmt.Println("文件不存在")
		}
	}else{
		fmt.Println(err)
	}

资源拷贝

案例: 将 D盘下 “壁纸.jpg” 拷贝到E盘图片文件下
用到 io包下的copy方法
在这里插入图片描述

package main

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

func main() {
	//将 d:/壁纸.jpg  拷贝到 e:/图片/abc.jpg
	destFileName := "e:/图片/abc.jpg"
	srcFileName := "d:/壁纸.jpg"
	CopyFile(destFileName,srcFileName)
}

/**
 * 文件拷贝的方法,将srcFileName拷贝到destFileName
 */
func CopyFile(destFileName string,srcFileName string)(writtern int64,err error){
    // 打开原文件
	srcFile, err := os.Open(srcFileName)
	if err != nil {
		panic(err)
	}
	defer srcFile.Close()
	// 构建Reader
	reader := bufio.NewReader(srcFile)

	//打开目的文件
	destFile, err := os.OpenFile(destFileName, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		panic(err)
	}
	defer destFile.Close()
	writer := bufio.NewWriter(destFile)
	written, err := io.Copy(writer, reader)
	writer.Flush()
	return written, err
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值