Golang檔案操作-下篇

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 ~
「其他文章」
- Gradle打包工具入門
- 服務網格和Istio初識-續
- 服務網格和Istio初識
- Golang與非對稱加密
- ack叢集Terway網路場景下的vSwitch擴容
- Golang與對稱加密
- 基於ack k8s叢集排程的方案設計
- 基於Dockerfile構建容器映象的最佳實踐
- Golang反射-下篇
- Golang反射-上篇
- Azure DevOps的使用入門
- Golang介面型別-下篇
- Golang介面型別-上篇
- 基於Python實現原生的登入驗證碼
- Golang開發命令列工具之flag包的使用
- Golang檔案操作-下篇
- k8s環境下處理容器時間問題的多種姿勢
- Golang基準測試
- 淺談Prometheus的資料儲存
- Golang單元測試