Go語(yǔ)言實(shí)現(xiàn)遍歷文件夾
path/filepath 包涉及到路徑操作時(shí),路徑分隔符使用 os.PathSeparator. Go是一個(gè)跨平臺(tái)的語(yǔ)言,不同系統(tǒng),路徑表示方式有所不同,比如 Unix 和 Windows 差別很大.本包能夠處理所有的文件路徑,不管是什么系統(tǒng).
Go標(biāo)準(zhǔn)庫(kù)中還有path, path 和 path/filepath 函數(shù)有點(diǎn)重復(fù),大部分情況下建議使用 path/filepath.
1.示例代碼:package path
package main;
import (
"fmt"
"path"
)
//go語(yǔ)言path包的學(xué)習(xí)
func main() {
//返回路徑的最后一個(gè)元素
fmt.Println(path.Base("./github.com/mojocn/c"));
//如果路徑為空字符串,返回.
fmt.Println(path.Base(""));
//如果路徑只有斜線,返回/
fmt.Println(path.Base("http:///"));
//返回等價(jià)的最短路徑
//1.用一個(gè)斜線替換多個(gè)斜線
//2.清除當(dāng)前路徑.
//3.清除內(nèi)部的..和他前面的元素
//4.以/..開(kāi)頭的,變成/
fmt.Println(path.Clean("./github.com/mojocn/../"));
//返回路徑最后一個(gè)元素的目錄
//路徑為空則返回.
fmt.Println(path.Dir("./github.com/mojocn/c"));
//返回路徑中的擴(kuò)展名
//如果沒(méi)有點(diǎn),返回空
fmt.Println(path.Ext("./github.com/mojocn/c/d.jpg"));
//判斷路徑是不是絕對(duì)路徑
fmt.Println(path.IsAbs("./github.com/mojocn/c"));
fmt.Println(path.IsAbs("/github.com/mojocn/c"));
//連接路徑,返回已經(jīng)clean過(guò)的路徑
fmt.Println(path.Join("./a", "b/c", "../d/"));
//匹配文件名,完全匹配則返回true
fmt.Println(path.Match("*", "a"));
fmt.Println(path.Match("*", "a/b/c"));
fmt.Println(path.Match("\\b", "b"));
//分割路徑中的目錄與文件
fmt.Println(path.Split("./github.com/mojocn/c/d.jpg"));
}2.示例代碼:package path/filepath
filepath.Join("C:/a", "/b", "/c") 拼接目錄
package main;
import (
"path/filepath"
"fmt"
"os"
)
//學(xué)習(xí)filepath包,兼容各操作系統(tǒng)的文件路徑
func main() {
//返回所給路徑的絕對(duì)路徑
path, _ := filepath.Abs("./1.txt");
fmt.Println(path);
//返回路徑最后一個(gè)元素
fmt.Println(filepath.Base("./1.txt"));
//如果路徑為空字符串,返回.
fmt.Println(filepath.Base(""));
//如果路徑只有斜線,返回/
fmt.Println(filepath.Base("http:///"));
//返回等價(jià)的最短路徑
//1.用一個(gè)斜線替換多個(gè)斜線
//2.清除當(dāng)前路徑.
//3.清除內(nèi)部的..和他前面的元素
//4.以/..開(kāi)頭的,變成/
fmt.Println(filepath.Clean("C:/github.com/mojocn/../c"));
fmt.Println(filepath.Clean("./1.txt"));
//返回路徑最后一個(gè)元素的目錄
//路徑為空則返回.
fmt.Println(filepath.Dir("./github.com/mojocn/c"));
fmt.Println(filepath.Dir("C:/github.com/mojocn/c"));
//返回鏈接文件的實(shí)際路徑
path2, _ := filepath.EvalSymlinks("1.lnk");
fmt.Println(path2);
//返回路徑中的擴(kuò)展名
//如果沒(méi)有點(diǎn),返回空
fmt.Println(filepath.Ext("./github.com/mojocn/c/d.jpg"));
//將路徑中的/替換為路徑分隔符
fmt.Println(filepath.FromSlash("./github.com/mojocn/c"));
//返回所有匹配的文件
match, _ := filepath.Glob("./*.go");
fmt.Println(match);
//判斷路徑是不是絕對(duì)路徑
fmt.Println(filepath.IsAbs("./github.com/mojocn/c"));
fmt.Println(filepath.IsAbs("C:/github.com/mojocn/c"));
//連接路徑,返回已經(jīng)clean過(guò)的路徑
fmt.Println(filepath.Join("C:/a", "/b", "/c"));
//匹配文件名,完全匹配則返回true
fmt.Println(filepath.Match("*", "a"));
fmt.Println(filepath.Match("*", "C:/github.com/mojocn/c"));
fmt.Println(filepath.Match("\\b", "b"));
//返回以basepath為基準(zhǔn)的相對(duì)路徑
path3, _ := filepath.Rel("C:/github.com/mojocn", "C:/github.com/mojocn/c/d/../e");
fmt.Println(path3);
//將路徑使用路徑列表分隔符分開(kāi),見(jiàn)os.PathListSeparator
//linux下默認(rèn)為:,windows下為;
fmt.Println(filepath.SplitList("C:/windows;C:/windows/system"));
//分割路徑中的目錄與文件
dir, file := filepath.Split("C:/github.com/mojocn/c/d.jpg");
fmt.Println(dir, file);
//將路徑分隔符使用/替換
fmt.Println(filepath.ToSlash("C:/github.com/mojocn"));
//返回分區(qū)名
fmt.Println(filepath.VolumeName("C:/github.com/mojocn/c"));
//遍歷指定目錄下所有文件
filepath.Walk("./", func(path string, info os.FileInfo, err error) error {
fmt.Println(path)
return nil
})
}3. 文件夾遍歷
Go 語(yǔ)言中進(jìn)行目錄遍歷的原生方法主要是以下3種:
filepath.Walk()ioutil.ReadDir()os.File.Readdir()
性能是越底層越高(上層其實(shí)是對(duì)底層API的封裝).
3.1 filepath.Walk()
遍歷根目錄(root)下的文件樹(shù),為樹(shù)中的每個(gè)文件或目錄(包括根目錄)調(diào)用walkFn.所有在訪問(wèn)文件和目錄時(shí)出現(xiàn)的錯(cuò)誤都由walkFn過(guò)濾. 遍歷按詞法順序進(jìn)行,這使得輸出是確定的,但對(duì)于非常大的目錄來(lái)說(shuō),遍歷可能是低效的. filepath.Walk()不會(huì)跟進(jìn)符號(hào)鏈接.
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
)
const (
layout = "2006-01-02 15:04:05"
)
func VisitFile(fp string, fi os.FileInfo, err error) error {
if err != nil {
fmt.Println(err) // can't walk here,
return nil // but continue walking elsewhere
}
if fi.IsDir() {
return nil // not a file. ignore.
}
// 過(guò)濾輸出內(nèi)容
matched, err := filepath.Match("*.txt", fi.Name())
if err != nil {
fmt.Println(err) // malformed pattern
return err // this is fatal.
}
if matched {
// fmt.Println(fp)
fmt.Printf("Name: %s, ModifyTime: %s, Size: %v\n", fp, fi.ModTime().Format(layout), fi.Size())
}
return nil
}
func main() {
var path = flag.String("path", ".", "The path to traverse.")
flag.Parse()
filepath.Walk(*path, VisitFile)
}3.2 ioutil.ReadDir
filepath.Walk()會(huì)自動(dòng)遍歷子目錄,但有些時(shí)候我們不希望這樣,如果只想看當(dāng)前目錄, 或手動(dòng)指定某幾級(jí)目錄中的文件,這個(gè)時(shí)候,可以使用 ioutil.ReadDir 進(jìn)行替代.
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
)
func main() {
var path = flag.String("path", ".", "The path to traverse.")
flag.Parse()
files, err := ioutil.ReadDir(*path)
if err != nil {
log.Fatal(err)
}
for _, file := range files {
fmt.Println(file.Name())
}
}3.3 os.File.os.File.Readdir
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
// https://stackoverflow.com/questions/14668850/list-directory-in-go/49196644#49196644
func main() {
var (
root string
err error
)
// root = "/home/manigandan/Desktop/Manigandan/sample"
root = "."
f, err := os.Open(root)
if err != nil {
return files, err
}
fileInfo, err := f.Readdir(-1)
f.Close()
if err != nil {
return files, err
}
for _, file := range fileInfo {
fmt.Println(file.Name())
}
}3.4 方法封裝的一個(gè)演示和對(duì)比
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
// https://stackoverflow.com/questions/14668850/list-directory-in-go/49196644#49196644
func main() {
var (
root string
files []string
err error
)
// root = "/home/manigandan/Desktop/Manigandan/sample"
root = "."
// filepath.Walk
files, err = FilePathWalkDir(root)
if err != nil {
panic(err)
}
// ioutil.ReadDir
files, err = IOReadDir(root)
if err != nil {
panic(err)
}
//os.File.Readdir
files, err = OSReadDir(root)
if err != nil {
panic(err)
}
for _, file := range files {
fmt.Println(file)
}
}
func FilePathWalkDir(root string) ([]string, error) {
var files []string
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
files = append(files, path)
}
return nil
})
return files, err
}
func IOReadDir(root string) ([]string, error) {
var files []string
fileInfo, err := ioutil.ReadDir(root)
if err != nil {
return files, err
}
for _, file := range fileInfo {
files = append(files, file.Name())
}
return files, nil
}
func OSReadDir(root string) ([]string, error) {
var files []string
f, err := os.Open(root)
if err != nil {
return files, err
}
fileInfo, err := f.Readdir(-1)
f.Close()
if err != nil {
return files, err
}
for _, file := range fileInfo {
files = append(files, file.Name())
}
return files, nil
}以上就是Go語(yǔ)言實(shí)現(xiàn)遍歷文件夾的詳細(xì)內(nèi)容,更多關(guān)于Go遍歷文件夾的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Go多協(xié)程并發(fā)環(huán)境下的錯(cuò)誤處理
這篇文章主要介紹了詳解Go多協(xié)程并發(fā)環(huán)境下的錯(cuò)誤處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Go使用Google?Gemini?Pro?API創(chuàng)建簡(jiǎn)單聊天機(jī)器人
這篇文章主要為大家介紹了Go使用Google?Gemini?Pro?API創(chuàng)建簡(jiǎn)單聊天機(jī)器人實(shí)現(xiàn)過(guò)程詳解,本文將通過(guò)最新的gemini?go?sdk來(lái)實(shí)現(xiàn)命令行聊天機(jī)器人2023-12-12
Go語(yǔ)言實(shí)現(xiàn)類似c++中的多態(tài)功能實(shí)例
Go本身不具有多態(tài)的特性,不能夠像Java、C++那樣編寫(xiě)多態(tài)類、多態(tài)方法。但是,使用Go可以編寫(xiě)具有多態(tài)功能的類綁定的方法。下面來(lái)一起看看吧2016-09-09
Go語(yǔ)言學(xué)習(xí)教程之聲明語(yǔ)法(譯)
Golang 就是類C的語(yǔ)法,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言學(xué)習(xí)教程之聲明語(yǔ)法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11
重學(xué)Go語(yǔ)言之錯(cuò)誤處理與異常機(jī)制詳解
Go語(yǔ)言的開(kāi)發(fā)者顯然覺(jué)得?try-catch被濫用了,因此?Go不支持使用?try-catch語(yǔ)句捕獲異常處理,那么,Go語(yǔ)言是如何定義和處理程序的異常呢,下面我們就來(lái)看看吧2023-08-08
Go語(yǔ)言中slice作為參數(shù)傳遞時(shí)遇到的一些“坑”
這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中slice作為參數(shù)傳遞時(shí)遇到的一些“坑”,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03

