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 ~
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/6dkmufKCBm2AzoO7aLa0AQ