Go 操作文件和文件夹

220 阅读4分钟

创建文件, 文件夹

可视化程序, 底层都是相关的命令

可以用代码来创建~

路径:

  • 相对路径
    • 相对当前目录(所在目录)的路径
    • . (./) 当前目录
    • .. (../) 上一级目录
  • 绝对路径
    • 从盘符开始的路径 (全路径)

目录操作

package main

import (
	"fmt"
	"os"
)

// 目录操作
func main() {
	// 打开文件夹(1.存在就打开; 2. 不存在, 就创建这个文件夹)
	// func Mkdir(name string, perm FileMode) error 函数传入 一个是路径 一个是对文件的权限
	// 这里设置的是赋予文件最高权限 0777 (os.ModePerm r -- 4 w -- 2 x -- 1)
	// 可以使用 os.MkdirAll() 来创建多级文件夹
	err := os.Mkdir("D:\Environment\GoWorks\src\studygo\basic_learn02\file1.txt", os.ModePerm)
	if err != nil { // 文件存在
		fmt.Println(err)
		return
	}
	fmt.Println("文件夹创建好了")
	// 删除 remove 删除指定的文件 (不会递归删除) 或者空文件夹
	// 若文件夹里面还有内容 (如多层文件), 可以使用 RemoveALL, 但这个命令比较危险, 谨慎使用
	err2 := os.Remove("D:\Environment\GoWorks\src\studygo\basic_learn02\file1.txt")
	if err2 != nil { // 出错了  The system cannot find the file specified.
		fmt.Println(err2)
		return
	}
	fmt.Println("文件已删除")
}

文件操作

文件, 就是一个类(结构体) -> 方法和属性

package main

import (
	"fmt"
	"os"
)

// 创建文件
func main() {
	// func Create(name string) (*File, error) 存在就打开, 不存在就先创建后打开
	// 返回的 file对象就是 新创建的文件
	file1, err := os.Create("b.go") // 这里可以放绝对路径or相对路径, 相对路径是相对于当前的文件夹
	if err != nil {
		fmt.Print(err)
	}
	fmt.Println(file1) // 返回的是指针地址(文件对象) 其指向是 b.go
	// 删除 (绝对/相对路径)
	os.Remove("a.go")
}

I/O 操作

电脑中的数据 是以二进制的形式存在 -> 按照不同的标准(底层就是不同的算法, 编码 解码), 约定的格式, 衍生出不同的文件格式 如 .jpg, .mp4 ...

大概过程: 1. 连接文件(流) 2. 读取/ 写入 3. 关闭连接

  1. 建立连接
package main

import (
	"fmt"
	"os"
)

// I/O 读操作
func main() {
	// 1. 先找到文件, 并返回文件对象 os.Open() 参数为路径
	// func Open(name string) (*File, error) 返回的是文件对象以及错误信息
	file, err := os.Open("aa.txt")
	if err != nil {
		fmt.Println(err)
		return
	}
	// 获取到对象, 那么可以对 对象进行操作
	fmt.Println(file)
	// 可能遇到访问权限不足, 那么可以通过指定权限 去访问文件
	// 参数: 文件名, 打开方式, 文件权限 (可以修改文件权限 :) )
	file2, err2 := os.OpenFile("aa.txt", os.O_WRONLY|os.O_RDONLY, os.ModePerm)
	if err2 != nil {
		fmt.Println(err2)
		return
	}
}
  1. 读取数据
package main

import (
	"fmt"
	"os"
)

// 读取文件数据
func main() {
	// 建立连接
	//file1, err := os.OpenFile("aa.txt", os.O_RDONLY|os.O_WRONLY, os.ModePerm)
	file1, err := os.Open("aa.txt")
	// 关闭连接
	defer file1.Close()
	if err != nil {
		fmt.Println(err)
		return
	}
	// fmt.Println(file1.Mode()) // os.Stat() => -rw-rw-rw-
	// 读代码
	// 可以先读到一个容器里, 然后再读容器内的数据
	bf := make([]byte, 1024, 1024)
	// 读取
	read_file, err := file1.Read(bf) // 相当于鼠标的光标 (向后移动) 将数据放在切片中
	// 当读取完文件 err 就是 EOF了 (end of file)
	if err != nil {
		return
	}
	fmt.Println(err)
	fmt.Println(read_file)
	fmt.Println(string(bf))
}
  1. 写文件
    建立连接的时候, 要注意的是若需要加内容, 而不想覆盖原文件的内容 需要在 OpenFile的第二个参数中多家一个操作权限 os.O_APPEND
package main

import (
	"fmt"
	"os"
)

// 写文件(需要考虑权限问题)
func main() {
	// 建立连接
	fileName := "aa.txt"
	file1, err := os.OpenFile(fileName, os.O_RDONLY|os.O_WRONLY|os.O_APPEND, os.ModePerm)
	if err != nil {
		fmt.Println("错误信息", err)
		return
	}
	// 操作
	// 准备待写入的数据 (字符)
	bs := []byte{65, 66, 67, 68, 69}
	n, err2 := file1.Write(bs)
	if err2 != nil {
		fmt.Println(err2)
		return
	}
	// 这样写 到源文件发现, 内容被覆盖, 原因在于OpenFile中设定的权限问题,
	// 应该设置多一个追加权限 os.O_APPEND (第二个参数), 这样才能在原本文件内容上追加内容(光标移到最后面)
	fmt.Println(n)
	// 写字符串
	n2, err3 := file1.WriteString("jhahahah")
	if err3 != nil {
		fmt.Println(err3)
		return
	}
	fmt.Println(n2)
}
  1. 文件复制

copy.go

package utils

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

// Copy 方法需要 参数: 源文件 目标文件 缓冲区大小
func Copy(source, destination string, bufferSize int) {
	// 读取文件
	sourceFiles, err := os.Open(source)
	if err != nil {
		fmt.Println("打开错误,", err)
	}
	// 输出文件 (写文件)
	destinationFiles, err2 := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, os.ModePerm)
	if err2 != nil {
		fmt.Println("打开文件出错,", err2)
	}
	defer sourceFiles.Close() // 文件拷贝
	defer destinationFiles.Close()
	buf := make([]byte, bufferSize)

	for {
		n, err := sourceFiles.Read(buf)
		if n == 0 || err == io.EOF { // 拷贝完文件内容了
			fmt.Println("文件拷贝完成")
			break
		} else if err != nil {
			fmt.Println("读取错误", err)
			return // 有错误, 需要 return 终止函数进行
		}
		fmt.Println(n) // 每次循环打印读取文件的比特数(b)
		// 将缓冲区的内容写到目标文件中
		_, err2 := destinationFiles.Write(buf[:n])
		if err2 != nil {
			fmt.Println(err2)
			return
		}
	}
}

可以在其他 .go 文件进行使用

不过 系统也给我们提供了 copy() 方法 io.Copy(dest Writer, src Reader) (written int64, err error){}