From 62266cd26b010cf89f4317e9dcebfbaf1e5dabcd Mon Sep 17 00:00:00 2001 From: huangzj Date: Thu, 30 Apr 2020 18:08:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(Go-Tool)=EF=BC=9A=E6=B7=BB=E5=8A=A0FileUti?= =?UTF-8?q?l.go=E3=80=81FileReadTool.go=E5=8D=95=E6=B5=8B=E7=B1=BB?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E4=BF=AE=E6=94=B9=E7=9B=B8=E5=BA=94?= =?UTF-8?q?bug-----IniTool.go=E4=BE=9D=E8=B5=96=E8=8E=B7=E5=8F=96=E4=B8=8D?= =?UTF-8?q?=E5=88=B0=EF=BC=8C=E6=B3=A8=E9=87=8A=E6=8E=89=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=81=E5=88=9B=E5=BB=BAArrayUtil.go=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=95=B0=E7=BB=84=E5=AF=B9=E5=BA=94=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 13 +- go.sum | 49 ++++- readme.md | 3 + test/array/ArrayUtil_test.go | 57 ++++++ test/emptyDirTest/1/11.txt | 10 + test/emptyDirTest/2/1/11.txt | 0 test/emptyDirTest/2/2222/4/4/111.txt | 0 test/emptyDirTest/2/2222/4/4/4/4/1211.txt | 0 test/emptyDirTest/3/11.txt | 0 test/file/FileReadTool_test.go | 21 ++ test/file/FileUtil_test.go | 53 +++++ test/file/FileWriteTool_test.go | 7 + util/array/ArrayUtil.go | 131 ++++++++++++ util/file/FileReadTool.go | 44 ++++ util/file/FileUtil.go | 186 ++++++++++++++--- util/ini/IniTool.go | 239 +++++++++++----------- 16 files changed, 660 insertions(+), 153 deletions(-) create mode 100644 test/array/ArrayUtil_test.go create mode 100644 test/emptyDirTest/1/11.txt create mode 100644 test/emptyDirTest/2/1/11.txt create mode 100644 test/emptyDirTest/2/2222/4/4/111.txt create mode 100644 test/emptyDirTest/2/2222/4/4/4/4/1211.txt create mode 100644 test/emptyDirTest/3/11.txt create mode 100644 test/file/FileReadTool_test.go create mode 100644 test/file/FileUtil_test.go create mode 100644 test/file/FileWriteTool_test.go create mode 100644 util/array/ArrayUtil.go diff --git a/go.mod b/go.mod index 00ef07a..a453196 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,15 @@ module Go-Tool go 1.13 -require github.com/go-ini/ini v1.55.0 // indirect +require ( + github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/kardianos/govendor v1.0.9 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/stretchr/testify v1.5.1 // indirect + golang.org/x/sys v0.0.0-20200428200454-593003d681fa // indirect + golang.org/x/tools v0.0.0-20200429213335-127c98bd7927 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect +) diff --git a/go.sum b/go.sum index bd37fb7..e8e952d 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,47 @@ -github.com/go-ini/ini v1.55.0 h1:0wVcG9udk2C3TGgmdIGKK9ScOZHZB5nbG+gwji9fhhc= -github.com/go-ini/ini v1.55.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75 h1:xGHheKK44eC6K0u5X+DZW/fRaR1LnDdqPHMZMWx5fv8= +github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 h1:3T8ZyTDp5QxTx3NU48JVb2u+75xc040fofcBaN+6jPA= +github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185/go.mod h1:cFRxtTwTOJkz2x3rQUNCYKWC93yP1VKjR8NUhqFxZNU= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/kardianos/govendor v1.0.9 h1:WOH3FcVI9eOgnIZYg96iwUwrL4eOVx+aQ66oyX2R8Yc= +github.com/kardianos/govendor v1.0.9/go.mod h1:yvmR6q9ZZ7nSF5Wvh40v0wfP+3TwwL8zYQp+itoZSVM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200428200454-593003d681fa h1:yMbJOvnfYkO1dSAviTu/ZguZWLBTXx4xE3LYrxUCCiA= +golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200429213335-127c98bd7927 h1:qunaQbmBN1l/xZt8mr6MLr8G/IOFiMbXvxYbGVqKlyw= +golang.org/x/tools v0.0.0-20200429213335-127c98bd7927/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/readme.md b/readme.md index 0710766..617f563 100644 --- a/readme.md +++ b/readme.md @@ -12,3 +12,6 @@ 2020/4/28 : 创建IniTool.go:包装int工具类,进行文件配置数据结构的读取,包括对应的使用例子(工具地址:https://ini.unknwon.cn/docs/howto/work_with_sections) +2020/4/30 :添加FileUtil.go、FileReadTool.go单测类代码,修改相应bug-----IniTool.go依赖获取不到,注释掉代码 + +2020/4/30 : 创建ArrayUtil.go,添加数组对应方法 \ No newline at end of file diff --git a/test/array/ArrayUtil_test.go b/test/array/ArrayUtil_test.go new file mode 100644 index 0000000..8912635 --- /dev/null +++ b/test/array/ArrayUtil_test.go @@ -0,0 +1,57 @@ +/* + * @Author : huangzj + * @Time : 2020/4/30 16:06 + * @Description:数组工具类测试 + */ + +package array + +import ( + "fmt" + "testing" +) + +type MM struct { + a int + b string + n NN +} + +type NN struct { + a int + b float64 +} + +func TestArray(t *testing.T) { + n := NN{ + a: 12, + b: 2.22, + } + n1 := NN{ + a: 12, + b: 2.22, + } + n2 := NN{ + a: 12, + b: 2.212, + } + x := MM{ + a: 1, + b: "1", + n: n, + } + y := MM{ + a: 1, + b: "1", + n: n1, + } + z := MM{ + a: 1, + b: "1", + n: n2, + } + + fmt.Print(x == y) + fmt.Print("\n\n测试一下") + fmt.Print(x == z) +} diff --git a/test/emptyDirTest/1/11.txt b/test/emptyDirTest/1/11.txt new file mode 100644 index 0000000..344c56e --- /dev/null +++ b/test/emptyDirTest/1/11.txt @@ -0,0 +1,10 @@ +12321321 +3213 + +3213213 +321321 +321321 +3 + +32132131 +321321321 diff --git a/test/emptyDirTest/2/1/11.txt b/test/emptyDirTest/2/1/11.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/emptyDirTest/2/2222/4/4/111.txt b/test/emptyDirTest/2/2222/4/4/111.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/emptyDirTest/2/2222/4/4/4/4/1211.txt b/test/emptyDirTest/2/2222/4/4/4/4/1211.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/emptyDirTest/3/11.txt b/test/emptyDirTest/3/11.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/file/FileReadTool_test.go b/test/file/FileReadTool_test.go new file mode 100644 index 0000000..f978e97 --- /dev/null +++ b/test/file/FileReadTool_test.go @@ -0,0 +1,21 @@ +/* + * @Author : huangzj + * @Time : 2020/4/30 14:55 + * @Description: 文件读取工具测试 + */ + +package file + +import ( + "Go-Tool/util/file" + "fmt" + "testing" +) + +func TestReadFileLineNum(t *testing.T) { + fmt.Print(file.ReadFileLineNum("F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\1\\11.txt")) +} + +func TestReadFileLineNumExceptEmptyLine(t *testing.T) { + fmt.Println(file.ReadFileLineNumExceptEmptyLine("F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\1\\11.txt")) +} diff --git a/test/file/FileUtil_test.go b/test/file/FileUtil_test.go new file mode 100644 index 0000000..ae7288c --- /dev/null +++ b/test/file/FileUtil_test.go @@ -0,0 +1,53 @@ +/* + * @Author : huangzj + * @Time : 2020/4/30 14:56 + * @Description: 文件工具测试 + */ + +package file + +import ( + "Go-Tool/util/file" + "fmt" + "testing" +) + +var ( + filePaths = [5]string{"F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\1\\11.txt", + "F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\2\\1\\11.txt", + "F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\2\\2222\\4\\4\\111.txt", + "F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\2\\2222\\4\\4\\4\\4\\1211.txt", + "F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest\\3\\11.txt"} +) + +func TestGetAllFileNameFromDir(t *testing.T) { + s := file.GetAllFileNameFromDir("F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest") + + for _, row := range s { + fmt.Print(row) + } +} + +func TestGetAllEmptyDir(t *testing.T) { + _, s := file.GetAllEmptyDir("F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest") + + for _, row := range s { + fmt.Print(fmt.Sprint(row, "\n\n")) + } +} + +func TestGetAllDir(t *testing.T) { + _, s := file.GetAllDir("F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest") + + for _, row := range s { + fmt.Print(row) + } +} + +func TestGetAllNotEmptyDir(t *testing.T) { + _, s := file.GetAllNotEmptyDir("F:\\Go个人代码\\src\\Go-Tool\\test\\emptyDirTest") + + for _, row := range s { + fmt.Print(row) + } +} diff --git a/test/file/FileWriteTool_test.go b/test/file/FileWriteTool_test.go new file mode 100644 index 0000000..033ecc5 --- /dev/null +++ b/test/file/FileWriteTool_test.go @@ -0,0 +1,7 @@ +/* + * @Author : huangzj + * @Time : 2020/4/30 14:56 + * @Description: 文件写入工具测试 + */ + +package file diff --git a/util/array/ArrayUtil.go b/util/array/ArrayUtil.go new file mode 100644 index 0000000..8f776c7 --- /dev/null +++ b/util/array/ArrayUtil.go @@ -0,0 +1,131 @@ +/* + * @Author : huangzj + * @Time : 2020/4/30 15:53 + * @Description: 数组工具 + * 这边测试了一下,go的结构体或者是非结构体类型,通过==比较的话,会校验到对应的每一个属性的值。 + * 也就是说就算两个结构体的指针地址不一样,但是他的所有属性值都是一样的话,==返回的结果也是true + * 这边直接在入口的地方进行了map、slice、interface、Func、chan、ptr、UnsafePointer 类型的拦截 + * 但是如果结构体中包含不能比较的类型,应该也是会报错 + */ + +package array + +import "reflect" + +var ( + invalid = [7]reflect.Kind{reflect.UnsafePointer, reflect.Map, reflect.Slice, + reflect.Interface, reflect.Func, reflect.Chan, reflect.Ptr} +) + +/* + * 返回数组中是否包含对应元素的结果 + */ +func Contains(list []interface{}, ele interface{}) bool { + if typeInvalid(reflect.TypeOf(ele).Kind()) { + panic("该类型不支持比较") + } + for _, row := range list { + if row == ele { + return true + } + } + return false +} + +/* + * 返回数组中是否不包含对应元素的结果 + */ +func NotContains(list []interface{}, ele interface{}) bool { + return !Contains(list, ele) +} + +/* + * 返回两个数组的所有元素是否相等的结果 + */ +func IsSameList(list, eList []interface{}) bool { + same := 0 + if len(list) != len(eList) { + return false + } + for _, l := range list { + for _, r := range eList { + if l == r { + same++ + break + } + } + } + return same == len(list) +} + +/* + * @param fList 传父集合 + * @param sList 传子集合 + * @return sList是不是fList的子集 + */ +func IsSubSet(fList, sList []interface{}) bool { + if len(fList) < len(sList) { + return false + } + for _, r := range sList { + if NotContains(fList, r) { + return false + } + } + return true +} + +/* + * 获取两个集合的交集 + */ +func Intersection(list, otherList []interface{}) []interface{} { + result := make([]interface{}, 0) + for _, row := range list { + if Contains(otherList, row) { + result = append(result, row) + } + } + return result +} + +/* + * 返回前一个数组包含,后一个数组不包含的结果(不是数量大的数组-数量小的数组) + */ +func DiffSet(cList, nList []interface{}) []interface{} { + result := make([]interface{}, 0) + for _, row := range cList { + if NotContains(nList, row) { + result = append(result, row) + } + } + return result +} + +/* + * 返回两个数组的并集,不包含重复的数据 + */ +func Union(aList, bList []interface{}) []interface{} { + result := make([]interface{}, 0) + + for _, row := range aList { + if NotContains(result, row) { + result = append(result, row) + } + } + for _, row := range bList { + if NotContains(bList, row) { + result = append(result, row) + } + } + return result +} + +func typeInvalid(k reflect.Kind) bool { + for _, row := range invalid { + if k == row { + return true + } + } + + return false +} diff --git a/util/file/FileReadTool.go b/util/file/FileReadTool.go index 02f5785..75b2b4f 100644 --- a/util/file/FileReadTool.go +++ b/util/file/FileReadTool.go @@ -66,3 +66,47 @@ func ReadByCircle(filePath string) (string, *err2.FileError) { return fs, nil } + +func ReadFileLineNum(filePath string) (int, *err2.FileError) { + file, err := os.Open(filePath) + if err != nil { + return 0, err2.ENewFileError(err) + } + defer file.Close() + + num := 0 + inputReader := bufio.NewReader(file) + for { + _, readerError := inputReader.ReadString('\n') + if readerError == io.EOF { + num++ + break + } + num++ + } + return num, nil +} + +func ReadFileLineNumExceptEmptyLine(filePath string) (int, *err2.FileError) { + file, err := os.Open(filePath) + if err != nil { + return 0, err2.ENewFileError(err) + } + defer file.Close() + + num := 0 + inputReader := bufio.NewReader(file) + for { + input, readerError := inputReader.ReadString('\n') + if readerError == io.EOF { + if input != "\r\n" && input != "" { + num++ + } + break + } + if input != "\r\n" && input != "" { + num++ + } + } + return num, nil +} diff --git a/util/file/FileUtil.go b/util/file/FileUtil.go index dec8b15..8d51f83 100644 --- a/util/file/FileUtil.go +++ b/util/file/FileUtil.go @@ -172,30 +172,8 @@ func GetAllFileFromDir(filePath string) []*os.File { return getFiles(filePath) } -/* - * @param - * @return - * @description 删除文件夹下面所有的空文件夹 - */ -func DeleteEmptyDir(filePath string) *err2.FileError { - err, is, _ := IsDirExist(filePath) - if err != nil { - return err2.ENewFileError(err) - } - if !is { - return err2.NewFileError("非文件夹") - } - - //拿到所有的空文件夹 - emptyDirList := getEmptyDir(filePath) - for _, row := range emptyDirList { - err := os.RemoveAll(row) - if err != nil { - return err2.ENewFileError(err) - } - } - - return nil +func GetAllFileNameFromDir(filePath string) []string { + return getFileNames(filePath) } /* @@ -211,25 +189,141 @@ func GetAllEmptyDir(dir string) (*err2.FileError, []string) { if !is { return err2.NewFileError("非文件夹"), nil } - return nil, getEmptyDir(dir) + + list := make([]string, 0) + errE, paths := GetAllDir(dir) + if errE != nil { + return errE, nil + } + for _, row := range paths { + err, is := isEmptyDir(row) + if err != nil { + return err, nil + } + if is { + list = append(list, row) + } + } + return nil, list } -func getEmptyDir(dir string) []string { - emptyDirList := make([]string, 0) +/* + * 获取所有非空文件夹的路径集合 + */ +func GetAllNotEmptyDir(dir string) (*err2.FileError, []string) { + err, is, _ := IsDirExist(dir) + if err != nil { + return err2.ENewFileError(err), nil + } + if !is { + return err2.NewFileError("非文件夹"), nil + } + files := make([]string, 0) + err1, aFiles := GetAllDir(dir) + if err1 != nil { + return err1, nil + } + err3, eFiles := GetAllEmptyDir(dir) + if err3 != nil { + return err3, nil + } + for _, a := range aFiles { + isIn := false + for _, e := range eFiles { + if a == e { + isIn = true + break + } + } + if !isIn { + files = append(files, a) + } + } + return nil, files +} + +/* + * 获取目录下的所有文件夹路径集合 + */ +func GetAllDir(dir string) (*err2.FileError, []string) { + err, is, _ := IsDirExist(dir) + if err != nil { + return err2.ENewFileError(err), nil + } + if !is { + return err2.NewFileError("非文件夹"), nil + } + return nil, getAllDir(dir) +} + +/* + * @param + * @return + * @description 删除文件夹下面所有的空文件夹 + */ +func DeleteEmptyDir(filePath string) *err2.FileError { + err, is, _ := IsDirExist(filePath) + if err != nil { + return err2.ENewFileError(err) + } + if !is { + return err2.NewFileError("非文件夹") + } + + //拿到所有的空文件夹 + err, emptyDirList := GetAllEmptyDir(filePath) + if err != nil { + return err + } + for _, row := range emptyDirList { + err := os.RemoveAll(row) + if err != nil { + return err2.ENewFileError(err) + } + } + + return nil +} + +func getAllDir(dir string) []string { + + dirList := make([]string, 0) info, err := ioutil.ReadDir(dir) if err != nil { return nil } for _, f := range info { if f.IsDir() { - list := getFiles(fmt.Sprint(dir, "\\", f.Name())) - if list == nil || len(list) == 0 { - emptyDirList = append(emptyDirList, dir) + list := getAllDir(fmt.Sprint(dir, "\\", f.Name())) + dirList = append(dirList, fmt.Sprint(dir, "\\", f.Name())) + if list != nil { + for _, l := range list { + dirList = append(dirList, l) + } } } } - return emptyDirList + return dirList +} + +func isEmptyDir(dir string) (*err2.FileError, bool) { + _, err := ioutil.ReadDir(dir) + if err != nil { + panic(err) + } + file := GetAllFileFromDir(dir) + for _, f := range file { + info, err := f.Stat() + if err != nil { + return err2.ENewFileError(err), false + } + if !info.IsDir() { + return nil, false + } + } + + return nil, true } func getFiles(filePath string) []*os.File { @@ -240,6 +334,7 @@ func getFiles(filePath string) []*os.File { } for _, f := range info { + //处理文件夹的部分 if f.IsDir() { list := getFiles(fmt.Sprint(filePath, "\\", f.Name())) if list != nil { @@ -247,8 +342,37 @@ func getFiles(filePath string) []*os.File { fileList = append(fileList, row) } } + } else { + //处理文件的部分 -- 使用读写方法打开文件 + thisFile, _ := os.OpenFile(fmt.Sprint(filePath, "\\", f.Name()), os.O_RDWR, 0666) + fileList = append(fileList, thisFile) } } return fileList } + +func getFileNames(filePath string) []string { + nameList := make([]string, 0) + info, err := ioutil.ReadDir(filePath) + if err != nil { + return nil + } + + for _, f := range info { + //处理文件夹的部分 + if f.IsDir() { + list := getFileNames(fmt.Sprint(filePath, "\\", f.Name())) + if list != nil { + for _, row := range list { + nameList = append(nameList, row) + } + } + } else { + //处理文件的部分 + nameList = append(nameList, fmt.Sprint(filePath, "\\", f.Name())) + } + } + + return nameList +} diff --git a/util/ini/IniTool.go b/util/ini/IniTool.go index 8fc9425..9d21ebc 100644 --- a/util/ini/IniTool.go +++ b/util/ini/IniTool.go @@ -6,122 +6,123 @@ package ini -import ( - "gopkg.in/ini.v1" - "time" -) - -func NewIniFileObj(iniPath string) (*ini.File, error) { - return ini.Load(iniPath) -} - -/* - * @param f ini文件对象 - * @return name->Section 的Map - * @description 通过所有Section对应的name->Section的map - */ -func GetSectionMap(f *ini.File) map[string]*ini.Section { - sectionMap := make(map[string]*ini.Section, 0) - sections := f.Sections() - for _, row := range sections { - sectionMap[row.Name()] = row - } - - return sectionMap -} - -/* - * @param f ini文件对象 - * @param sectionName 区间名字 - * @return key->value的map - * @description 返回对应Section名字的key-value的map结构,如果没有这个section返回空map - */ -func GetKeyValueBySection(f *ini.File, sectionName string) map[string]string { - keyValueMap := make(map[string]string, 0) - sec := f.Section(sectionName) - for _, row := range sec.Keys() { - keyValueMap[row.Name()] = row.Value() - } - - return keyValueMap -} - -/* - * @param f ini文件对象 - * @return {section -> [{key->value}]} - * @description 返回每个区间对应的所有key、value的结构,具体返回结构如下: - * { - * "sectionName1":[ - "keyName1":KeyValue1 - * ..... - * ], - * ..... - * } -*/ -func GetKeyValueByALLSection(f *ini.File) { - secMap := make(map[string][]map[string]string, 0) - for _, row := range f.Sections() { - keyList := make([]map[string]string, 0) - for _, r := range row.Keys() { - keyMap := make(map[string]string, 0) - keyMap[r.Name()] = r.Value() - keyList = append(keyList, keyMap) - } - - secMap[row.Name()] = keyList - } -} - -/* - * 使用例子,官网说明文档可以看到,这边补记录一下. - */ -func example(cfg *ini.File) { - //获取键值时设定候选值,如果没有找到,则返回默认值 - cfg.Section("SectionName").Key("KeyName").In("default", []string{"str", "arr", "types"}) - cfg.Section("SectionName").Key("KeyName").InFloat64(1.1, []float64{1.25, 2.5, 3.75}) - cfg.Section("SectionName").Key("KeyName").InInt(5, []int{10, 20, 30}) - cfg.Section("SectionName").Key("KeyName").InInt64(10, []int64{10, 20, 30}) - cfg.Section("SectionName").Key("KeyName").InUint(4, []uint{3, 6, 9}) - cfg.Section("SectionName").Key("KeyName").InUint64(8, []uint64{3, 6, 9}) - //这边的三个时间不一样,为了防止报错这么写... - cfg.Section("SectionName").Key("KeyName").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time.Now(), time.Now(), time.Now()}) - cfg.Section("SectionName").Key("KeyName").InTime(time.Now(), []time.Time{time.Now(), time.Now(), time.Now()}) // RFC3339 - - //验证获取的值是否在指定范围内,第一个参数是默认值,后面两个值分别是范围 - cfg.Section("SectionName").Key("KeyName").RangeFloat64(0.0, 1.1, 2.2) - cfg.Section("SectionName").Key("KeyName").RangeInt(0, 10, 20) - cfg.Section("SectionName").Key("KeyName").RangeInt64(0, 10, 20) - cfg.Section("SectionName").Key("KeyName").RangeTimeFormat(time.RFC3339, time.Now(), time.Now(), time.Now()) - cfg.Section("SectionName").Key("KeyName").RangeTime(time.Now(), time.Now(), time.Now()) // RFC3339 - - //自动分割键值到切片,当存在无效输入时,使用零值代替 - // Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] - // Input: how, 2.2, are, you -> [0.0 2.2 0.0 0.0] - cfg.Section("SectionName").Key("KeyName").Strings(",") - cfg.Section("SectionName").Key("KeyName").Float64s(",") - cfg.Section("SectionName").Key("KeyName").Ints(",") - cfg.Section("SectionName").Key("KeyName").Int64s(",") - cfg.Section("SectionName").Key("KeyName").Uints(",") - cfg.Section("SectionName").Key("KeyName").Uint64s(",") - cfg.Section("SectionName").Key("KeyName").Times(",") - - //自动分割键值到切片,从结果切片中剔除无效输入 - // Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] - // Input: how, 2.2, are, you -> [2.2] - cfg.Section("SectionName").Key("KeyName").ValidFloat64s(",") - cfg.Section("SectionName").Key("KeyName").ValidInts(",") - cfg.Section("SectionName").Key("KeyName").ValidInt64s(",") - cfg.Section("SectionName").Key("KeyName").ValidUints(",") - cfg.Section("SectionName").Key("KeyName").ValidUint64s(",") - cfg.Section("SectionName").Key("KeyName").ValidTimes(",") - - //自动分割键值到切片,当存在无效输入时,直接返回错误 - // Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] - // Input: how, 2.2, are, you -> error - cfg.Section("SectionName").Key("KeyName").StrictFloat64s(",") - cfg.Section("SectionName").Key("KeyName").StrictInts(",") - cfg.Section("SectionName").Key("KeyName").StrictInt64s(",") - cfg.Section("SectionName").Key("KeyName").StrictUints(",") - cfg.Section("SectionName").Key("KeyName").StrictUint64s(",") - cfg.Section("SectionName").Key("KeyName").StrictTimes(",") -} +// +//import ( +// "go-ini/ini" +// "time" +//) +// +//func NewIniFileObj(iniPath string) (*ini.File, error) { +// return ini.Load(iniPath) +//} +// +///* +// * @param f ini文件对象 +// * @return name->Section 的Map +// * @description 通过所有Section对应的name->Section的map +// */ +//func GetSectionMap(f *ini.File) map[string]*ini.Section { +// sectionMap := make(map[string]*ini.Section, 0) +// sections := f.Sections() +// for _, row := range sections { +// sectionMap[row.Name()] = row +// } +// +// return sectionMap +//} +// +///* +// * @param f ini文件对象 +// * @param sectionName 区间名字 +// * @return key->value的map +// * @description 返回对应Section名字的key-value的map结构,如果没有这个section返回空map +// */ +//func GetKeyValueBySection(f *ini.File, sectionName string) map[string]string { +// keyValueMap := make(map[string]string, 0) +// sec := f.Section(sectionName) +// for _, row := range sec.Keys() { +// keyValueMap[row.Name()] = row.Value() +// } +// +// return keyValueMap +//} +// +///* +// * @param f ini文件对象 +// * @return {section -> [{key->value}]} +// * @description 返回每个区间对应的所有key、value的结构,具体返回结构如下: +// * { +// * "sectionName1":[ +// "keyName1":KeyValue1 +// * ..... +// * ], +// * ..... +// * } +//*/ +//func GetKeyValueByALLSection(f *ini.File) { +// secMap := make(map[string][]map[string]string, 0) +// for _, row := range f.Sections() { +// keyList := make([]map[string]string, 0) +// for _, r := range row.Keys() { +// keyMap := make(map[string]string, 0) +// keyMap[r.Name()] = r.Value() +// keyList = append(keyList, keyMap) +// } +// +// secMap[row.Name()] = keyList +// } +//} +// +///* +// * 使用例子,官网说明文档可以看到,这边补记录一下. +// */ +//func example(cfg *ini.File) { +// //获取键值时设定候选值,如果没有找到,则返回默认值 +// cfg.Section("SectionName").Key("KeyName").In("default", []string{"str", "arr", "types"}) +// cfg.Section("SectionName").Key("KeyName").InFloat64(1.1, []float64{1.25, 2.5, 3.75}) +// cfg.Section("SectionName").Key("KeyName").InInt(5, []int{10, 20, 30}) +// cfg.Section("SectionName").Key("KeyName").InInt64(10, []int64{10, 20, 30}) +// cfg.Section("SectionName").Key("KeyName").InUint(4, []uint{3, 6, 9}) +// cfg.Section("SectionName").Key("KeyName").InUint64(8, []uint64{3, 6, 9}) +// //这边的三个时间不一样,为了防止报错这么写... +// cfg.Section("SectionName").Key("KeyName").InTimeFormat(time.RFC3339, time.Now(), []time.Time{time.Now(), time.Now(), time.Now()}) +// cfg.Section("SectionName").Key("KeyName").InTime(time.Now(), []time.Time{time.Now(), time.Now(), time.Now()}) // RFC3339 +// +// //验证获取的值是否在指定范围内,第一个参数是默认值,后面两个值分别是范围 +// cfg.Section("SectionName").Key("KeyName").RangeFloat64(0.0, 1.1, 2.2) +// cfg.Section("SectionName").Key("KeyName").RangeInt(0, 10, 20) +// cfg.Section("SectionName").Key("KeyName").RangeInt64(0, 10, 20) +// cfg.Section("SectionName").Key("KeyName").RangeTimeFormat(time.RFC3339, time.Now(), time.Now(), time.Now()) +// cfg.Section("SectionName").Key("KeyName").RangeTime(time.Now(), time.Now(), time.Now()) // RFC3339 +// +// //自动分割键值到切片,当存在无效输入时,使用零值代替 +// // Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] +// // Input: how, 2.2, are, you -> [0.0 2.2 0.0 0.0] +// cfg.Section("SectionName").Key("KeyName").Strings(",") +// cfg.Section("SectionName").Key("KeyName").Float64s(",") +// cfg.Section("SectionName").Key("KeyName").Ints(",") +// cfg.Section("SectionName").Key("KeyName").Int64s(",") +// cfg.Section("SectionName").Key("KeyName").Uints(",") +// cfg.Section("SectionName").Key("KeyName").Uint64s(",") +// cfg.Section("SectionName").Key("KeyName").Times(",") +// +// //自动分割键值到切片,从结果切片中剔除无效输入 +// // Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] +// // Input: how, 2.2, are, you -> [2.2] +// cfg.Section("SectionName").Key("KeyName").ValidFloat64s(",") +// cfg.Section("SectionName").Key("KeyName").ValidInts(",") +// cfg.Section("SectionName").Key("KeyName").ValidInt64s(",") +// cfg.Section("SectionName").Key("KeyName").ValidUints(",") +// cfg.Section("SectionName").Key("KeyName").ValidUint64s(",") +// cfg.Section("SectionName").Key("KeyName").ValidTimes(",") +// +// //自动分割键值到切片,当存在无效输入时,直接返回错误 +// // Input: 1.1, 2.2, 3.3, 4.4 -> [1.1 2.2 3.3 4.4] +// // Input: how, 2.2, are, you -> error +// cfg.Section("SectionName").Key("KeyName").StrictFloat64s(",") +// cfg.Section("SectionName").Key("KeyName").StrictInts(",") +// cfg.Section("SectionName").Key("KeyName").StrictInt64s(",") +// cfg.Section("SectionName").Key("KeyName").StrictUints(",") +// cfg.Section("SectionName").Key("KeyName").StrictUint64s(",") +// cfg.Section("SectionName").Key("KeyName").StrictTimes(",") +//}