go语言标准库(包) filepth 文件路径包文档

本文档详细介绍了Go语言的filepath包,包括获取当前操作系统的目录分割符、获取绝对路径、路径处理函数如Base、Clean、Join等,以及模式匹配、文件扩展名获取和遍历磁盘等功能。适合Go语言初学者,特别是对跨平台路径处理感兴趣的开发者阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录


介绍

filepath是跨平台的(Windows/Linux/Unix/Plan9)
考虑到官网的pkg文档实在是对初学者不友好,所以
我专门针对案例使用了Windows系统下的操作案例。
初学者在看到官网的example时,往往不是使用Linux
系统,所以案例会让初学者感到陌生。才专门开这样
的文章。

获取当前操作系统的目录分割符

通过常量获取:

sep := string(filepath.Separator)

例如我们在windows中,输出的就是“\”符号,在Linux系统中就是“/”符号,使用这个常量的目的是,我们编写跨平台程序的时候,如果需要操作目录/文件,往往我们需要链接目录或文件的字符串,如果我们直接输入“/”或则“\”那么不利于跨平台,所以当我们需要链接文件名称/目录名称的时候,需要使用分割符时,请使用 filepath.Separator 常量。记得string转换一下类型,因为其本身的类型是 untype rune


获取绝对路径

函数签名:

func Abs(path string) (string, error)

例如我想知道我编写的go程序编译后,运行时所处于的磁盘的路径(绝对路径)可以这样:

abspath, err := filepath.Abs(".")
if err != nil {
	panic(err)
}

abspath 你以可以理解为 current path,即程序执行时所处的目录路径。

当然,这是一个附带功能,毕竟 Abs() 主要的意思还是“返回路径的绝对表示”,只是当给定的路径不是绝对路径时,才将其与当前工作路径链接,形成一个绝对路径。


获取路径Base

假如我当前程序所在的路径为:“D:\go_project\src\test”
即我的程序所处的目录是N级,上面这个,我程序所处的目录级别分别是:D:、go_project、src、test,就N为4级。那么我要获取程序所在的目录名称,而不是完整的目录名称,我应该这样做:

abspath, err := filepath.Abs(".")
if err != nil {
	panic(err)
}
base := filepath.Base(abspath)

Base() 函数将会把输入的路径字符串内容,取出最后部分,当然如果最后一个字符为分隔符,它会先删除分隔符。
如果路径为空,则会返回".“及当前目录的意思,这样一个字符串内容。如果全部是分割符组成的话,那么Base函数会返回一个”“或”/"的分割符字符串。这里的 Base() ,可以理解为目录路径所指向的最后目的地(Base Location)


Clean暂无例子,仅翻译:

Clean() 通过纯粹的词法处理返回等同于path的最短路径名。 它迭代应用以下规则,直到无法进行进一步处理:

1.用一个替换多个Separator元素。
2.消除每一个。 路径名元素(当前目录)。
3.消除每个内部..路径名称元素(父目录)
    以及它之前的非..元素。
4.消除开始根路径的元素:
    也就是说,在路径的开头用“/”替换“/ ..”,
    假设Separator是'/'。

只有当它表示根目录时,返回的路径以斜杠结尾,例如Unix上的 “/” 或Windows上的 “X:\” 。
最后,任何出现的斜杠都会被 Separator 替换。
如果此过程的结果是空字符串,则 Clean() 返回字符串 “.” 。

这个例子不用写,可以理解为帮我们清理路径字符串中的斜杠,以当前操作系统的 filepath.Separator 作为标准替换。

另请参阅Rob Pike的“Plan 9中的词汇文件名称或获得Dot-Dot Right”https://9p.io/sys/doc/lexnames.html


识别路径字符串中的目录路径

假如在Linux系统中或Windows系统中,程序处理如下列这样一些路径字符串:
“D:/go_project/src/test/go.mod”
“D:/go_project/src/test/readme”
“~/.vim”
“~/.vimrc”
这里就有问题了!例如go.mod是一个文件还是一个目录?我们会go语言的同学一看就知道这绝逼应该是一个文件,那么readme是文件还是一个目录呢?这个就不好说了。毕竟没有.ext 扩展名,文件还是目录,就是我们人类都要 ls -l 或 dir 命令看看吧?包括下面的.vim是目录还是文件,.vimrc是文件还是目录?对于程序来讲,必须要明确,所以我们可以通过 filepath.Dir() 函数来处理这个事情。

path := "D:/go_project/src/test/go.mod"
fmt.Println(filepath.Dir(path))

运行输出的结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
D:\go_project\src\test
PASS
ok      test    0.117s

D:\go_project\src\test
我们可以看到,程序中,我故意使用了/而不是\来作为路径分隔符,但是 Dir() 函数执行后的结果来看,已经帮我们转换成了当前操作系统的分隔符了。如果我们给定的字符串参数是空字符串"",则输出 “.” 表明当前目录,如果字符串全部是分隔符,则会输出最后一个分割符号作为结果。


EvalSymlinks 暂无例子

在评估任何符号链接后,EvalSymlinks() 返回路径名。 如果path是相对的,则结果将相对于当前目录,除非其中一个组件是绝对符号链接。 EvalSymlinks() 在结果上调用Clean。

func EvalSymlinks(path string) (string, error)

Eval 是Evaluation评估的意思,Sym 是Symbol符号的意思,合起来就是评估/评测符号链接的意思。
假 如 我 传 入 的 参 数 字 符 串 , 是 一 个 符 号 链 接 的 相 对 / 绝 对 路 径 \color{#ff0000}{假如我传入的参数字符串,是一个符号链接的相对/绝对路径} /
返回的结果内容会再调用一次Clean进行输出。如果符号链接文件的路径是相对的,返回相对,是绝对的返回绝对,如果符号链接指向的链接目标的路径是绝对的,则返回其绝对路径,就这么个意思。


获取文件扩展名Ext

当我们确定了一个文件的路径后,我们想要将这个文件的扩展名提取出来,可以这样:

path := "D:/go_project/src/test/go.mod"
extname := filepath.Ext(path)
fmt.Println(extname)

输出结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
.mod
PASS
ok      test    0.328s

.mod
结果就是获取到这个文件的扩展是.mod,如果不要这个点可以:

if len(extname) > 1 {
	if strings.Contains(extname, ".") {
		extname = extname[1:]
	}
}

首先扩展名如果能够获取到,那么一定是>1的长度哪怕是一个 .o 或 .a 这样的文件扩展,那么也可以不用 strings.Contains判断一下,而直接使用 extname = extname[1:] 这样就可以将那个.号给去除了。不要怀疑,如果文件名是一个 xxxx. 这样的形式,文件名中的.会被作为返回值,但长度为1,而不是 > 1。
如果文件名是 xxxx,没有.没有.后面的扩展名,则返回值为空串 “”,如果文件名是 github.com.readme 那么扩展名返回的是最后一个点后的内容,即: .readme


处理/替换路径分隔符

path := "D:/go_project/src/test/go.mod"
fromSlash := filepath.FromSlash(path)
fmt.Println(fromSlash)

输出结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
D:\go_project\src\test\go.mod
PASS
ok      test    0.379s

FromSlash 的作用就是将路径中的分割符统一为当前操作系统中的分割符号。内部是其实用的是 strings.ReplaceAll 函数处理:
FromSlash的实现
所以这个函数,与Clean不同的是,它仅仅是将路径中的分割符做一次标准化替换而已。
我们也可以看到源代码中的第一次判断,即分隔符如果是Linux操作系统“/”,这直接返回path,也就是不处理。换句话说,Windows系统中处理含有 / 的路径字符串才会有效果。


模式匹配-查找/统计文件数量

函数签名:

func Glob(pattern string) (matches []string, err error)

这里先给出代码例子:

var (
	matches []string
	err     error
)
pattern := "C:\\Windows\\System32\\*.exe"
if matches, err = filepath.Glob(pattern); err != nil {
	panic(err)
}
fmt.Println(len(matches))

作用是,通过将通配符*加入路径,形成模式pattern字符串,然后作为参数传递给Glob,目的是统计C:\Windows\System32目录中到底有多少个exe文件。当然matches字符串数组内存放的是没有给.exe文件的绝对路径(包含文件名),太长就不贴这里了。
上面的代码输出:

PS D:\go_project\src\test> go test --test.run TestFilePath
613
PASS
ok      test    0.189s

也就是找到了613个exe文件。
如果没有匹配的文件,Glob将返回匹配pattern或nil的所有文件的名称。 模式的语法与Match中的相同。 该模式可以描述分层名称,例如/ usr / * / bin / ed(假设分隔符为’/’)。
G l o b 忽 略 文 件 系 统 错 误 , 例 如 读 取 目 录 的 I / O 错 误 。 \color{#ff0000}{Glob忽略文件系统错误,例如读取目录的I / O错误。 } GlobI/O
当 模 式 格 式 错 误 时 , 唯 一 可 能 返 回 的 错 误 是 E r r B a d P a t t e r n 。 \color{#ff0000}{当模式格式错误时,唯一可能返回的错误是ErrBadPattern。} ErrBadPattern


不推荐使用HasPrefix

HasPrefix存在历史兼容性,不应使用。
不推荐使用:HasPrefix不遵循路径边界,并且在需要时不会忽略大小写。


报告路径是否为绝对路径IsAbs

func IsAbs(path string) (b bool)

IsAbs reports whether the path is absolute. // 这个和Abs的意思差不多,不赘述了。


路径链接的正确姿势Join

我们链接路径字符串这样吗?

programPath := APath + string(filepath.Separator) + BPath

… 这样做没问题,但缺乏规范,而且如果APath的内容是:/home/gopher/.vim/bundle/,那么我们再链接就变成//了,这怕是不太好。
所以规范的路径元素添加(链接字符串)操作应该使用filepath包给我们提供的Join函数。

下面的一个例子是,我从系统环境变量中得到Windows系统的安装路径,因为这个可能不是标准的C:\Windows,也许是D:\Win10也是说不定的事情,所以通过系统的环境变量来获取是最安全的。然后在链接目录路径元素System32,例子如下:

env := os.Environ()
var envMap = make(map[string]string)
for _, v := range env {
	kv := strings.Split(v, "=")
	envMap[kv[0]] = kv[1]
}
v, ok := envMap["windir"]
if ok {
	sys32 := filepath.Join(v, "System32") // 将System32路径元素添加到 v 这个路径元素后面
	fmt.Println(sys32)
}

输出结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
C:\WINDOWS\System32
PASS
ok      test    0.654s

这样做的好处是,我们不用关心系统的Separator,Join函数的签名:

func Join(elem ...string) string

形参列表是多参数式,可以链接多个路径元素。
Join将任意数量的路径元素连接到单个路径中,必要时添加Separator。 在结果上调用Clean; 特别是,忽略所有空字符串。 在Windows上,当且仅当第一个路径元素是UNC路径时,结果才是UNC路径。
(UNC Universal Naming Convention 通用命名惯例)
例如:

file://127.0.0.1/C:/     本地C盘
file://localhost/D:/     本地D盘
file:///F:/              本地F盘

模式匹配Match

函数签名:

func Match(pattern, name string) (matched bool, err error)

匹配报告名称是否与shell文件名模式匹配。 模式语法是:

pattern模式:
 						{term} 
term术语:
						'*' 匹配任何非分隔符字符序列
						'?' 匹配任何单个非分隔符
						'[' ['^'] { character-range } ']'
						字符类 (必须是非空的)
						c 匹配字符 c (c != '*','?','\\','[')
						'\\'c 匹配字符 c
						
character-range字符范围:
						c 匹配字符 c (c!='\\','-',']')
						'\\' c 匹配字符 c
						lo '-' hi 匹配字符c表示 lo <= c <= hi

匹配需要模式匹配所有名称,而不仅仅是子字符串。 当模式格式错误时,唯一可能返回的错误是 ErrBadPattern
在Windows上,禁用转义。 相反,’\'被视为路径分隔符。

比如看看下面这个例子,我们匹配error.log的模式:

var (
	err error
	ret bool
)
fileName := "error.log"
pattern1 := "*ros*"
pattern2 := "*ror*"
if ret, err = filepath.Match(pattern1, fileName); err != nil {
	panic(err)
}
fmt.Println(ret)

if ret, err = filepath.Match(pattern2, fileName); err != nil {
	panic(err)
}
fmt.Println(ret)

输出结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
false
true
PASS
ok      test    0.193s

第一个模式匹配 ros 对 error.log 显然是不匹配,而第二个模式 ror 匹配到了 error.log ,换句话说,我的模式和路径/文件名是否是模式匹配的。当然,模式匹配的是字符串,字符串内容,即文件名以及文件/路径是否存在,不是这个函数考虑的事情。

再来一个例子:

var (
	err error
	ret bool
)
fileName := "data20190411.log"
pattern := "data[{0-9}]*"
if ret, err = filepath.Match(pattern, fileName); err != nil {
	panic(err)
}
fmt.Println(ret)

再来一个对比一下:

var (
	err error
	ret bool
)
fileName := "data20190411.log"
pattern := "data201905[0-9]*"
if ret, err = filepath.Match(pattern, fileName); err != nil {
	panic(err)
}
fmt.Println(ret)

上上面的例子,我的模式是"data[{0-9}]*" 那么可以匹配到 datayyyymmdd.log,没啥可说的。
上面的例子,我们需要匹配5月份的所有.log文件,那么文件名是04月份的,肯定就匹配不到。
这个Match函数还是很重要,我们从目录拿到了所有文件名后,我们可以直接通过filepath.Match()函数去模式匹配我们需要的文件。
当然这个事情使用regexp包(正则表达式包)也能解决,但是我们需要:

pattern := "xxxxxxx"
reg := regexp.MusthCompile(pattern)
reg.MatchString(fileName)

但原则是我们如果能少导包就少 import pacakge ,路径/文件的处理能用 filepath 完成的话就尽可能只用它,除非我们要做的功能它无法覆盖到,才去导入对应的功能包。


获取相对路径Rel

函数签名:

func Rel(basepath, targpath string) (string, error)

Rel返回一个相对路径,该路径在使用插入分隔符连接到basepath时在词法上等效于targpath。 也就是说,Join(basepath,Rel(basepath,targpath))等同于targpath本身。 成功时,返回的路径将始终相对于basepath,即使basepath和targpath不共享任何元素。 如果无法相对于basepath创建targpath,或者如果需要知道当前工作目录,则会返回错误。 Rel调用结果清理。

那么我们来看看在Windows系统下的一个小例子:

path := []string{
	"D:\\go_project\\src\\test",
	"D:\\go_project\\src",
	"D:\\go_project",
}
base := "D:\\go_project\\src"
var ret string
for _, v := range path {
	ret, _ = filepath.Rel(base, v)
	fmt.Println(ret)
}

我们看看输出结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
test
.
..
PASS
ok      test    0.379s

首先我给定的base,即 Rel() 的第一个参数是:"D:/go_project/src" , 而第二个处理的参数分别来自与 path []string , 分别是:

D:/go_project/src/test
D:/go_project/src
D:/go_project

=> 将以上三个路径分别和 base => D:/go_project/src 进行相对路径求解

我们看到执行的结果分别是:

test
.
..

即:

D:/go_project/src -> D:/go_project/src/test 求出的相对路径是 test
D:/go_project/src -> D:/go_project/src 求出的相对路径是 . (即当前目录)
D:/go_project -> D:/go_project/src 求出的相对路径是 .. (即上一级目录)

换句话说,Rel(base, target string) 第一个参数,是我们需要处理的路径,相对于第二个目标路径进行处理,获取两者之间的关系,是:
./test
.


路径中的目录与文件名分割Split

函数签名:

func Split(path string) (dir, file string)

Split() 将最后的Separator之后的路径立即分割,将其分成目录和文件名组件。 如果路径中没有Separator,则Split()会返回一个空目录,并将文件设置为path。 返回的值具有path = dir + file的属性。

我们看看下面的例子:

path := "D:\\go_project\\src\\test\\abc"
dir, file := filepath.Split(path)
fmt.Println(dir)
fmt.Println(file)

执行结果:

PS D:\go_project\src\test> go test --test.run TestFilePath
D:\go_project\src\test\
abc
PASS
ok      test    0.468s

Split() 分 割 , 并 不 会 检 测 最 后 一 个 分 割 符 后 的 是 目 录 还 是 文 件 \color{#ff0000}{分割,并不会检测最后一个分割符后的是目录还是文件}
从功能上来说,Split() 只是将路径中,最后一个分割符后的内容分割出来返回file,将分割后前面的内容返回到dir,但实际上我例子中实际情况是abc是目录,而不是文件,所以安全的做法是,在分割之前要想办法判断出,路径是指向的是目录还是文件,确定是文件后,才进行Split() 分割。


路径元素分割SplitList

函数签名:

func SplitList(path string) []string

SplitList() 拆分由特定于操作系统的 ListSeparator 连接的路径列表,通常位于PATH或GOPATH环境变量中。 与 strings.Split() 不同,SplitList() 在传递空字符串时返回空切片。

一个小例子:

env := os.Environ()
var envMap = make(map[string]string)
for _, v := range env {
	kv := strings.Split(v, "=")
	envMap[kv[0]] = kv[1]
}
v, ok := envMap["Path"]
if ok {
	pathItem := filepath.SplitList(v)
	for _, v := range pathItem {
		fmt.Println(v)
	}
}

我们先从 os.Environ() 获取环境变量 []string ,string数组中的存放形式是: k=v,例如"windir=C:\Windows",所以我们使用 strings.Split() 将其分割并写入 envMap map[string]string 中,那么我们需要将系统的环境变量 Path 的内容使用 filepath.SplitList 分割出来。

输出结果如下:

PS D:\go_project\src\test> go test --test.run TestFilePath
C:\WINDOWS
C:\WINDOWS\System32\Wbem
C:\WINDOWS\System32\WindowsPowerShell\v1.0\
C:\Users\gamec\.dnx\bin
C:\Program Files\Microsoft DNX\Dnvm\
C:\Program Files\Microsoft SQL Server\120\Tools\Binn\
C:\Program Files\Microsoft SQL Server\130\Tools\Binn\
C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\
C:\Program Files (x86)\Microsoft Emulator Manager\1.0\
C:\Program Files (x86)\GTK2-Runtime\bin
D:\Applications\phpStudy32\php56n
D:\phalcon-devtools-master
C:\Program Files\nodejs\
C:\Program Files\Java\jdk1.8.0_91\bin
D:\apache-ant-1.9.7\bin
C:\ProgramData\ComposerSetup\bin
D:\ffmpeg\bin
D:\Applications\sqlite3
D:\Android\Android Studio\gradle\gradle-5.4.1\bin
D:\Applications\phpStudy_2016_x64\php56n
C:\WINDOWS\system32
C:\Program Files\TortoiseGit\bin
C:\Program Files (x86)\GtkSharp\2.12\bin
C:\WINDOWS\System32\OpenSSH\
D:\Applications\ffmpeg-4.1.1-win64-static\bin
%GOPATH%\bin
D:\Applications\Microsoft VS Code\bin
%REDISPATH%
D:\Applications\Git\cmd
D:\Go\bin
%GOPATH%\bin
%GOPATH%
C:\Program Files (x86)\Bitvise SSH Client
%UPXHOME%
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
C:\Users\gamec\AppData\Local\VanDyke Software\Clients\
D:\Applications\Microsoft VS Code\bin
C:\Users\gamec\AppData\Roaming\npm
C:\Users\gamec\AppData\Roaming\Composer\vendor\bin
C:\Users\gamec\AppData\Local\Microsoft\WindowsApps
C:\Users\gamec\go\bin
PASS
ok      test    0.814s

这时候的 pathItem []string 已经获取了系统的 Path 的所有分割项了。


将Win风格的路径分割符转换为Linux的分隔符ToSlash

函数签名:

func ToSlash(path string) string

ToSlash() 返回用斜杠(’/’)字符替换路径中每个分隔符的结果。 多个分隔符由多个斜杠替换。

那这次的例子我还是利用上面的例子修改一下:

env := os.Environ()
var envMap = make(map[string]string)
for _, v := range env {
	kv := strings.Split(v, "=")
	envMap[kv[0]] = kv[1]
}
v, ok := envMap["Path"]
if ok {
	pathItem := filepath.SplitList(v)
	for _, v := range pathItem {
		pslash := filepath.ToSlash(v) // 这里我用ToSlash处理后,\ 分割符全部处理成 / 分割符
		fmt.Println(pslash)
	}
}

输出结果这里不贴了。因为就是将有斜杠分隔符全部处理成左斜杠分隔符。


卷名称获取VolumeName

函数签名:

func VolumeName(path string) string

VolumeName() 返回前导卷名称。 给定“C:\foo\bar”,它在Windows上返回“C:”。 给定“\host\share\foo”,它返回“\host\share”。 在其他平台上它返回""(空字符串)。(支持Windows/UNC)

例子A:

path := "C:\\Windows\\System32\\"
volumeName := filepath.VolumeName(path)
fmt.Println(volumeName)

得到的结果:

C:

表明卷名称为"C:", AKA"分区的盘符号"(windows A-Z, A,B是软盘 C~Z可能是硬盘分区的盘符,可能是Z倒叙过来的几个常常用于网路映射的盘符)

例子B:

path := "\\\\192.168.0.108\\share"
volumeName := filepath.VolumeName(path)
fmt.Println(volumeName)

执行的结果是:

PS D:\go_project\src\test> go test --test.run TestFilePath
\\192.168.0.108\share
PASS
ok      test    0.125s

\\192.168.0.108 是局域网中,某台Windows的系统,开启了网络共享后,我们可以通过 \\host\xxxx 来访问的路径。四个右斜杠是用来转义 \\ 的。


遍历磁盘Walk与WalkFunc

函数签名:

func Walk(root string, walkFn WalkFunc) error

Walk遍历以root为根的文件树,为树中的每个文件或目录调用walkFn,包括root。 访问文件和目录时出现的所有错误都由walkFn过滤。 这些文件以词法顺序进行,这使得输出具有确定性,但这意味着对于非常大的目录,Walk可能效率低下。 步行不遵循符号链接。

例子:

/*
   _____       __   __             _  __ 
  ╱ ____|     |  ╲/   |           | |/ / 
 | |  __  ___ |  ╲ /  | __  _ _ __| ' /  
 | | |_ |/ _ ╲| |╲ /| |/ _`  | '__|  <   
 | |__| |  __/| |   | (  _|  | |  | . ╲  
  ╲_____|╲___ |_|   |_|╲__,_ |_|  |_|╲_╲ 
 可爱飞行猪❤: golang83@outlook.com  ???
 Author Name: GeMarK.VK.Chow奥迪哥  ???
 Creaet Time: 2019/05/18 - 19:25:03
 ProgramFile: test.go
 Description:
			遍历磁盘Walk 与 WalkFunc
*/

package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"time"
)

var (
	err       error
	slog      *log.Logger
	ptrFS     *os.File
	logFlags  int
	fileFlags int
	count     uint32
)

func init() {
	logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile
	fileFlags = os.O_CREATE | os.O_RDWR | os.O_APPEND
	ptrFS, err = os.OpenFile("error.log", fileFlags, 0)
	if err != nil {
		fmt.Println("OpenLogFileError:", err)
		os.Exit(1)
	}
	slog = new(log.Logger)
	slog.SetPrefix("[TestInfo]")
	slog.SetFlags(logFlags)
	slog.SetOutput(ptrFS)
}

func main() {
	// Unified processing panic 统一处理panic
	defer errorHandle()
	walk()
}

func walk() {
	// Testing stdout message. 输出消息
	slog.Printf("this function its test filepath package Walk function.\r\n")

	// count time
	start := time.Now()

	// set root is C:\ 定义根目录为 C 盘根目录
	root := "C:\\"
	// 调用 filepath.Walk 函数(root, 函数对象参数(路径,文件信息,错误)返回error对象)
	err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			slog.Printf("%s\r\n", err)
			// if return err, program will Exit(1)... so, skip err to continue program.
			// 这里输出错误就好,不然程序就终止了....
		}
		if info.IsDir() {
			count++
			// fmt.Printf("Found Directory: [%s]\r\r\n", info.Name())
			// 如果这里打印的话,太多多了,所以仅仅操作计数就可以了。
		}
		return nil
	})
	if err != nil {
		panic(err)
	}
	end := time.Now().Sub(start)
	// write info to log file 将统计信息写入日志文件
	slog.Printf("Found: %d %s", count, " directories.\r\n")
	slog.Printf("Consumes:%s", end.String())
	fmt.Println("Walk func complete. Found:", count, " directories.", "Consumes:", end.String())
}

func errorHandle() {
	if panic_rev := recover(); panic_rev != nil {
		slog.Printf("ErrorsInfo:%s\r\n", panic_rev)
		ptrFS.Close()
		os.Exit(1)
	}
}

当然,也有可能会出现某个目录看着存在,但实际上已经不存在了(例如Windows.old)我清理磁盘,使用清理系统文件,删除了Windows更新安装后,遗留的文件,这个时候,可能就会出现这样的目录,需要重新启动后,才能解决。当然系统中很有可能存在其他有问题的文件夹,上述的源代码会将这种意外错误记录在error.log中含有“ErrorsInfo”内容的行。而且也可以通过error.log文件中的信息了解哪些文件夹可能权限是只能Administrotar或者根本只能System权限才能访问的。如果没有致命错误,将会输出大致存在多少目录数,以及消费的时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值