Golang文件操作-下篇
目录
1、文件的重命名和删除
2、文件路径的获取
3、判断文件是否存在
4、获取文件的信息
5、拷贝文件
6、目录操作
7、常见目录
1、文件的重命名和删除
os
包自带重命名和删除的方法
package main
import "os"
func main() {
os.Rename("user.log", "user.v2.log")
os.Remove("user.txt")
}
2、文件路径的获取
文件路径操作包括对文件路径、文件名等
package main
import (
"fmt"
"os"
"path/filepath"
)
func main() {
fmt.Println(filepath.Abs(".")) // 获取当前路径,和Getwd相同
fmt.Println(os.Args)
fmt.Println(filepath.Abs(os.Args[0])) // 当前程序运行的绝对路径
path, _ := filepath.Abs(os.Args[0])
fmt.Println(filepath.Base("c:/test/a.txt")) // basename 文件名 a.txt
fmt.Println(filepath.Base("c:/test/xxxx/")) // basename 目录名 xxxx
fmt.Println(filepath.Base(path))
fmt.Println(filepath.Dir("c:/test/a.txt")) // 获取目录名 c:/test
fmt.Println(filepath.Dir("c:/test/xxxx/")) // 获取目录名 c:/test/xxxx
fmt.Println(filepath.Dir(path))
fmt.Println(filepath.Ext("c:/test/a.txt")) // 获取扩展名 .txt
fmt.Println(filepath.Ext("c:/test/xxxx/a")) // 空
fmt.Println(filepath.Ext(path)) // 空
dirPath := filepath.Dir(path)
iniPath := dirPath + "/conf/ip.ini"
fmt.Println(iniPath) // 拼接配置文件路径
fmt.Println(filepath.Join(dirPath, "conf", "ip.ini")) // 组装配置文件路径
fmt.Println(filepath.Glob("./[ab]*/*.go")) // 找文件 找当前路径下目录名包含ab,以go文件结尾
filepath.Walk(".", func(path string, fileInfo os.FileInfo, err error) error { // 遍历路径下所有子孙目录
fmt.Println(path, fileInfo.Name())
return nil
})
}
3、判断文件是否存在
主要是通过os
包的open
方法打开文件,并接收返回的错误信息,给os
包的IsNotExist
函数判断,返回一个布尔值
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("xxx")
if err != nil {
if os.IsNotExist(err){
fmt.Println("文件不存在")
}
} else {
file.Close()
}
}
4、获取文件的信息
获取文件信息及文件夹的子文件信息lstat
:如果是超链接,获取的是超链接的信息stat
:如果是超链接,获取的是目标文件的信息
package main
import (
"fmt"
"os"
)
func main() {
for _, path := range []string{"user.txt", "reader.go", "aaa"} { // 循环文件名
fileInfo, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err){
fmt.Println("文件不存在")
}
} else {
fmt.Println(fileInfo.Name(), fileInfo.IsDir(), fileInfo.Size(), fileInfo.ModTime())
//文件名 是否是目录 大小 修改时间
//user.txt false 12 2021-08-30 16:20:54.853211783 +0800 CST
//reader.go false 387 2021-08-30 15:57:06.860696025 +0800 CST
if fileInfo.IsDir() { // 获取目录下的子目录及文件
dirfile, err := os.Open(path)
if err == nil {
defer dirfile.Close()
//childrens, _ := dirfile.Readdir(-1) // 获取所有的子目录
//for _, children := range childrens {
// fmt.Println(children.Name(), children.IsDir(), children.Size(), children.ModTime())
//}
names, _ := dirfile.Readdirnames(-1)
for _, name := range names {
fmt.Println(name)
}
}
}
}
}
}
5、拷贝文件
copyfile
功能的实现,主要借助于golang
自带的命令行解析工具flag
(这个在后面的文章中会专门介绍),通过bufio
读取并写入文件
package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
)
func copyfile(src, dest string) {
srcfile, err := os.Open(src)
if err != nil {
fmt.Println(err)
} else {
defer srcfile.Close()
destfile, err := os.Create(dest)
if err != nil {
fmt.Println(err)
} else {
defer destfile.Close()
reader := bufio.NewReader(srcfile)
writer := bufio.NewWriter(destfile)
bytes := make([]byte, 1024*1024*10) // 缓冲区大小
for {
n, err := reader.Read(bytes)
if err != nil {
if err != io.EOF {
fmt.Println(err)
}
break
}
writer.Write(bytes[:n])
//destfile.Write(bytes[:n])
writer.Flush()
}
}
}
}
func main() {
src := flag.String("s", "", "src file")
dest := flag.String("d", "", "dest file")
help := flag.Bool("h", false, "help")
flag.Usage = func() {
fmt.Println(`
Usage: copyfile -s srcfile -d destfile
Options:
`)
flag.PrintDefaults()
}
flag.Parse()
if *help || *src == "" || *dest == "" {
flag.Usage()
} else {
copyfile(*src, *dest)
}
}
支持递归拷贝目录及目录下的文件
package main
import (
"bufio"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
)
func copyFile(src, dest string) {
srcFile, err := os.Open(src)
if err != nil {
fmt.Println(err)
} else {
defer srcFile.Close()
destFile, err := os.Create(dest)
if err != nil {
fmt.Println(err)
} else {
defer destFile.Close()
reader := bufio.NewReader(srcFile)
writer := bufio.NewWriter(destFile)
bytes := make([]byte, 1024*1024*10) // 缓冲区大小
for {
n, err := reader.Read(bytes)
if err != nil {
if err != io.EOF {
fmt.Println(err)
}
break
}
writer.Write(bytes[:n])
//destfile.Write(bytes[:n])
writer.Flush()
}
}
}
}
func copyDir(src, dst string) {
files, err := ioutil.ReadDir(src)
if err == nil {
os.Mkdir(dst, os.ModePerm) // 目标路径不存在先创建目录
for _, file := range files {
if file.IsDir() { // 目录 递归调用
copyDir(filepath.Join(src, file.Name()), filepath.Join(dst, file.Name()))
} else { // 文件 拷贝文件
copyFile(filepath.Join(src, file.Name()), filepath.Join(dst, file.Name()))
}
}
}
}
func main() {
src := flag.String("s", "", "src file")
dest := flag.String("d", "", "dest file")
help := flag.Bool("h", false, "help")
flag.Usage = func() {
fmt.Println(`
Usage: copyfile -s srcfile -d destfile
Options:
`)
flag.PrintDefaults()
}
flag.Parse()
if *help || *src == "" || *dest == "" {
flag.Usage()
} else {
// src是否存在 不存在则退出
// src 文件 copyfile
// dst 判断 存在 退出
// src 目录 copydir
// dst 判断 不存在 copy
// dst 存在 目录
// dst 存在 不是目录 退出
if _, err := os.Stat(*dest); err == nil {
fmt.Println("目的文件已存在")
return
} else {
if !os.IsNotExist(err) {
fmt.Println("目的文件获取错误", err)
}
}
if info, err := os.Stat(*src); err != nil {
if os.IsNotExist(err) {
fmt.Println("源文件不存在")
} else {
fmt.Println("源文件获取错误: ", err)
}
} else {
if info.IsDir() {
copyDir(*src, *dest)
} else {
copyFile(*src, *dest)
}
}
}
}
6、目录操作
目录的创建、删除和重命名
package main
import "os"
func main() {
os.Mkdir("test01", 0644)
os.Rename("test01", "test02")
os.Remove("test02")
}
创建子目录,当父目录不存在的时候需要使用mkdirAll
,并设置权限(创建目录除了给定的权限还要加上系统的Umask
,Go
也是如实遵循这种约定,Umask
是权限的补码,用于设置创建文件和文件夹默认权限的)
package main
import (
"os"
"syscall"
)
func main() {
//os.Mkdir("test01", 0644) // 如果目录存在会报错
//os.Rename("test01", "test02")
//os.Remove("test02")
//err := os.Mkdir("test01/xxx", 0644)
//fmt.Println(err) // mkdir test01/xxx: no such file or directory
mask := syscall.Umask(0) // 改为 0000 八进制
defer syscall.Umask(mask) // 改为原来的 umask
err := os.MkdirAll("test01/test/", 0777) // MkdirAll创建
if err != nil {
panic(err)
}
os.RemoveAll("test01")
}
7、常见目录
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.TempDir()) // 临时目录
fmt.Println(os.UserCacheDir()) // 用户缓存目录
fmt.Println(os.UserHomeDir()) // 用户家目录
fmt.Println(os.Getwd()) // 当前绝对目录
}
See you ~
欢迎进群一起进行技术交流
加群方式:公众号消息私信“加群”或加我好友再加群均可
评论