improve internal/debug,glog,garray,gfile

This commit is contained in:
John
2019-07-27 11:34:04 +08:00
parent 86f51f1e4a
commit 538b282f43
21 changed files with 416 additions and 218 deletions

View File

@ -5,3 +5,63 @@
// You can obtain one at https://github.com/gogf/gf.
package garray
import "strings"
func defaultComparatorInt(a, b int) int {
if a < b {
return -1
}
if a > b {
return 1
}
return 0
}
func defaultComparatorStr(a, b string) int {
return strings.Compare(a, b)
}
// quickSortInt is the quick-sorting algorithm implements for int.
func quickSortInt(values []int, comparator func(a, b int) int) {
if len(values) <= 1 {
return
}
mid, i := values[0], 1
head, tail := 0, len(values)-1
for head < tail {
if comparator(values[i], mid) > 0 {
values[i], values[tail] = values[tail], values[i]
tail--
} else {
values[i], values[head] = values[head], values[i]
head++
i++
}
}
values[head] = mid
quickSortInt(values[:head], comparator)
quickSortInt(values[head+1:], comparator)
}
// quickSortStr is the quick-sorting algorithm implements for string.
func quickSortStr(values []string, comparator func(a, b string) int) {
if len(values) <= 1 {
return
}
mid, i := values[0], 1
head, tail := 0, len(values)-1
for head < tail {
if comparator(values[i], mid) > 0 {
values[i], values[tail] = values[tail], values[i]
tail--
} else {
values[i], values[head] = values[head], values[i]
head++
i++
}
}
values[head] = mid
quickSortStr(values[:head], comparator)
quickSortStr(values[head+1:], comparator)
}

View File

@ -22,8 +22,8 @@ import (
type SortedIntArray struct {
mu *rwmutex.RWMutex
array []int
unique *gtype.Bool // Whether enable unique feature(false)
comparator func(v1, v2 int) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
unique *gtype.Bool // Whether enable unique feature(false)
comparator func(a, b int) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b)
}
// NewSortedIntArray creates and returns an empty sorted array.
@ -33,23 +33,23 @@ func NewSortedIntArray(safe ...bool) *SortedIntArray {
return NewSortedIntArraySize(0, safe...)
}
// NewSortedIntArrayComparator creates and returns an empty sorted array with specified comparator.
// The parameter <safe> used to specify whether using array in concurrent-safety which is false in default.
func NewSortedIntArrayComparator(comparator func(a, b int) int, safe ...bool) *SortedIntArray {
array := NewSortedIntArray(safe...)
array.comparator = comparator
return array
}
// NewSortedIntArraySize create and returns an sorted array with given size and cap.
// The parameter <safe> used to specify whether using array in concurrent-safety,
// which is false in default.
func NewSortedIntArraySize(cap int, safe ...bool) *SortedIntArray {
return &SortedIntArray{
mu: rwmutex.New(safe...),
array: make([]int, 0, cap),
unique: gtype.NewBool(),
comparator: func(v1, v2 int) int {
if v1 < v2 {
return -1
}
if v1 > v2 {
return 1
}
return 0
},
mu: rwmutex.New(safe...),
array: make([]int, 0, cap),
unique: gtype.NewBool(),
comparator: defaultComparatorInt,
}
}

View File

@ -22,8 +22,8 @@ import (
type SortedArray struct {
mu *rwmutex.RWMutex
array []interface{}
unique *gtype.Bool // Whether enable unique feature(false)
comparator func(v1, v2 interface{}) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
unique *gtype.Bool // Whether enable unique feature(false)
comparator func(a, b interface{}) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b)
}
// NewSortedArray creates and returns an empty sorted array.
@ -32,14 +32,14 @@ type SortedArray struct {
// if it returns value < 0, means v1 < v2;
// if it returns value = 0, means v1 = v2;
// if it returns value > 0, means v1 > v2;
func NewSortedArray(comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
func NewSortedArray(comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
return NewSortedArraySize(0, comparator, safe...)
}
// NewSortedArraySize create and returns an sorted array with given size and cap.
// The parameter <safe> used to specify whether using array in concurrent-safety,
// which is false in default.
func NewSortedArraySize(cap int, comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
func NewSortedArraySize(cap int, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
return &SortedArray{
mu: rwmutex.New(safe...),
unique: gtype.NewBool(),
@ -51,7 +51,7 @@ func NewSortedArraySize(cap int, comparator func(v1, v2 interface{}) int, safe .
// NewSortedArrayFrom creates and returns an sorted array with given slice <array>.
// The parameter <safe> used to specify whether using array in concurrent-safety,
// which is false in default.
func NewSortedArrayFrom(array []interface{}, comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
func NewSortedArrayFrom(array []interface{}, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
a := NewSortedArraySize(0, comparator, safe...)
a.array = array
sort.Slice(a.array, func(i, j int) bool {
@ -63,7 +63,7 @@ func NewSortedArrayFrom(array []interface{}, comparator func(v1, v2 interface{})
// NewSortedArrayFromCopy creates and returns an sorted array from a copy of given slice <array>.
// The parameter <safe> used to specify whether using array in concurrent-safety,
// which is false in default.
func NewSortedArrayFromCopy(array []interface{}, comparator func(v1, v2 interface{}) int, safe ...bool) *SortedArray {
func NewSortedArrayFromCopy(array []interface{}, comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
newArray := make([]interface{}, len(array))
copy(newArray, array)
return NewSortedArrayFrom(newArray, comparator, safe...)

View File

@ -10,8 +10,6 @@ import (
"bytes"
"encoding/json"
"math"
"sort"
"strings"
"github.com/gogf/gf/g/container/gtype"
"github.com/gogf/gf/g/internal/rwmutex"
@ -23,8 +21,8 @@ import (
type SortedStringArray struct {
mu *rwmutex.RWMutex
array []string
unique *gtype.Bool // Whether enable unique feature(false)
comparator func(v1, v2 string) int // Comparison function(it returns -1: v1 < v2; 0: v1 == v2; 1: v1 > v2)
unique *gtype.Bool // Whether enable unique feature(false)
comparator func(a, b string) int // Comparison function(it returns -1: a < b; 0: a == b; 1: a > b)
}
// NewSortedStringArray creates and returns an empty sorted array.
@ -34,17 +32,23 @@ func NewSortedStringArray(safe ...bool) *SortedStringArray {
return NewSortedStringArraySize(0, safe...)
}
// NewSortedStringArrayComparator creates and returns an empty sorted array with specified comparator.
// The parameter <safe> used to specify whether using array in concurrent-safety which is false in default.
func NewSortedStringArrayComparator(comparator func(a, b string) int, safe ...bool) *SortedStringArray {
array := NewSortedStringArray(safe...)
array.comparator = comparator
return array
}
// NewSortedStringArraySize create and returns an sorted array with given size and cap.
// The parameter <safe> used to specify whether using array in concurrent-safety,
// which is false in default.
func NewSortedStringArraySize(cap int, safe ...bool) *SortedStringArray {
return &SortedStringArray{
mu: rwmutex.New(safe...),
array: make([]string, 0, cap),
unique: gtype.NewBool(),
comparator: func(v1, v2 string) int {
return strings.Compare(v1, v2)
},
mu: rwmutex.New(safe...),
array: make([]string, 0, cap),
unique: gtype.NewBool(),
comparator: defaultComparatorStr,
}
}
@ -54,7 +58,7 @@ func NewSortedStringArraySize(cap int, safe ...bool) *SortedStringArray {
func NewSortedStringArrayFrom(array []string, safe ...bool) *SortedStringArray {
a := NewSortedStringArraySize(0, safe...)
a.array = array
sort.Strings(a.array)
quickSortStr(a.array, a.comparator)
return a
}
@ -72,7 +76,7 @@ func (a *SortedStringArray) SetArray(array []string) *SortedStringArray {
a.mu.Lock()
defer a.mu.Unlock()
a.array = array
sort.Strings(a.array)
quickSortStr(a.array, a.comparator)
return a
}
@ -82,7 +86,7 @@ func (a *SortedStringArray) SetArray(array []string) *SortedStringArray {
func (a *SortedStringArray) Sort() *SortedStringArray {
a.mu.Lock()
defer a.mu.Unlock()
sort.Strings(a.array)
quickSortStr(a.array, a.comparator)
return a
}

View File

@ -17,7 +17,7 @@ import (
const (
gMAX_DEPTH = 1000
gFILTER_KEY = "/g/internal/debug/stack.go"
gFILTER_KEY = "/g/internal/debug/debug.go"
)
var (
@ -84,14 +84,14 @@ func StackWithFilter(filter string, skip ...int) string {
}
// CallerPath returns the absolute file path along with its line number of the caller.
func Caller(skip ...int) string {
func Caller(skip ...int) (path string, line int) {
return CallerWithFilter("", skip...)
}
// CallerPathWithFilter returns the absolute file path along with its line number of the caller.
//
// The parameter <filter> is used to filter the path of the caller.
func CallerWithFilter(filter string, skip ...int) string {
func CallerWithFilter(filter string, skip ...int) (path string, line int) {
number := 0
if len(skip) > 0 {
number = skip[0]
@ -104,12 +104,12 @@ func CallerWithFilter(filter string, skip ...int) string {
if strings.Contains(file, gFILTER_KEY) {
continue
}
return fmt.Sprintf(`%s:%d`, file, line)
return file, line
} else {
break
}
}
return ""
return "", -1
}
// callerFromIndex returns the caller position exclusive of the debug package.

View File

@ -18,21 +18,16 @@ import (
"os/user"
"path/filepath"
"runtime"
"sort"
"strings"
"time"
"github.com/gogf/gf/g/container/gtype"
"github.com/gogf/gf/g/text/gregex"
"github.com/gogf/gf/g/text/gstr"
"github.com/gogf/gf/g/util/gconv"
)
const (
// Separator for file system.
Separator = string(filepath.Separator)
// Default perm for file opening.
gDEFAULT_PERM = 0666
Separator = string(filepath.Separator) // Separator for file system.
gDEFAULT_PERM = 0666 // Default perm for file opening.
)
var (
@ -333,58 +328,6 @@ func Chmod(path string, mode os.FileMode) error {
return os.Chmod(path, mode)
}
// ScanDir returns all sub-files with absolute paths of given <path>,
// It scans directory recursively if given parameter <recursive> is true.
func ScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
list, err := doScanDir(path, pattern, recursive...)
if err != nil {
return nil, err
}
if len(list) > 0 {
sort.Strings(list)
}
return list, nil
}
// doScanDir is an internal method which scans directory
// and returns the absolute path list of files that are not sorted.
//
// The pattern parameter <pattern> supports multiple file name patterns,
// using the ',' symbol to separate multiple patterns.
//
// It scans directory recursively if given parameter <recursive> is true.
func doScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
list := ([]string)(nil)
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
names, err := file.Readdirnames(-1)
if err != nil {
return nil, err
}
for _, name := range names {
path := fmt.Sprintf("%s%s%s", path, Separator, name)
if IsDir(path) && len(recursive) > 0 && recursive[0] {
array, _ := doScanDir(path, pattern, true)
if len(array) > 0 {
list = append(list, array...)
}
}
// If it meets pattern, then add it to the result list.
for _, p := range strings.Split(pattern, ",") {
if match, err := filepath.Match(strings.TrimSpace(p), name); err == nil && match {
path = Abs(path)
if path != "" {
list = append(list, path)
}
}
}
}
return list, nil
}
// Abs returns an absolute representation of path.
// If the path is not absolute it will be joined with the current
// working directory to turn it into an absolute path. The absolute
@ -516,54 +459,6 @@ func homeWindows() (string, error) {
return home, nil
}
// MainPkgPath returns absolute file path of package main,
// which contains the entrance function main.
//
// It's only available in develop environment.
//
// Note1: Only valid for source development environments,
// IE only valid for systems that generate this executable.
// Note2: When the method is called for the first time, if it is in an asynchronous goroutine,
// the method may not get the main package path.
func MainPkgPath() string {
path := mainPkgPath.Val()
if path != "" {
if path == "-" {
return ""
}
return path
}
for i := 1; i < 10000; i++ {
if _, file, _, ok := runtime.Caller(i); ok {
// <file> is separated by '/'
if gstr.Contains(file, "/gf/g/") {
continue
}
if Ext(file) != ".go" {
continue
}
// separator of <file> '/' will be converted to Separator.
for path = Dir(file); len(path) > 1 && Exists(path) && path[len(path)-1] != os.PathSeparator; {
files, _ := ScanDir(path, "*.go")
for _, v := range files {
if gregex.IsMatchString(`package\s+main`, GetContents(v)) {
mainPkgPath.Set(path)
return path
}
}
path = Dir(path)
}
} else {
break
}
}
// If it fails finding the path, then mark it as "-",
// which means it will never do this search again.
mainPkgPath.Set("-")
return ""
}
// See os.TempDir().
func TempDir() string {
return os.TempDir()

View File

@ -29,7 +29,7 @@ func Replace(search, replace, path, pattern string, recursive ...bool) error {
// ReplaceFunc replaces content for files under <path> with callback function <f>.
// The parameter <pattern> specifies the file pattern which matches to be replaced.
// It does replacement recursively if given parameter <recursive> is true.
func ReplaceFunc(f func(content string) string, path, pattern string, recursive ...bool) error {
func ReplaceFunc(f func(path, content string) string, path, pattern string, recursive ...bool) error {
files, err := ScanDir(path, pattern, recursive...)
if err != nil {
return err
@ -38,7 +38,7 @@ func ReplaceFunc(f func(content string) string, path, pattern string, recursive
result := ""
for _, file := range files {
data = GetContents(file)
result = f(data)
result = f(file, data)
if data != result {
if err = PutContents(file, result); err != nil {
return err

96
g/os/gfile/gfile_scan.go Normal file
View File

@ -0,0 +1,96 @@
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gfile
import (
"os"
"path/filepath"
"sort"
"strings"
)
// ScanDir returns all sub-files with absolute paths of given <path>,
// It scans directory recursively if given parameter <recursive> is true.
func ScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
isRecursive := true
if len(recursive) > 0 {
isRecursive = recursive[0]
}
list, err := doScanDir(path, pattern, isRecursive, false)
if err != nil {
return nil, err
}
if len(list) > 0 {
sort.Strings(list)
}
return list, nil
}
// ScanDirFile returns all sub-files with absolute paths of given <path>,
// It scans directory recursively if given parameter <recursive> is true.
//
// Note that it returns only files, exclusive of directories.
func ScanDirFile(path string, pattern string, recursive ...bool) ([]string, error) {
isRecursive := true
if len(recursive) > 0 {
isRecursive = recursive[0]
}
list, err := doScanDir(path, pattern, isRecursive, true)
if err != nil {
return nil, err
}
if len(list) > 0 {
sort.Strings(list)
}
return list, nil
}
// doScanDir is an internal method which scans directory
// and returns the absolute path list of files that are not sorted.
//
// The pattern parameter <pattern> supports multiple file name patterns,
// using the ',' symbol to separate multiple patterns.
//
// It scans directory recursively if given parameter <recursive> is true.
func doScanDir(path string, pattern string, recursive bool, onlyFile bool) ([]string, error) {
list := ([]string)(nil)
file, err := os.Open(path)
if err != nil {
return nil, err
}
defer file.Close()
names, err := file.Readdirnames(-1)
if err != nil {
return nil, err
}
filePath := ""
isDir := false
for _, name := range names {
filePath = path + Separator + name
isDir = IsDir(filePath)
if isDir && recursive {
array, _ := doScanDir(filePath, pattern, true, onlyFile)
if len(array) > 0 {
list = append(list, array...)
}
}
// It returns only files.
if isDir && onlyFile {
continue
}
// If it meets pattern, then add it to the result list.
for _, p := range strings.Split(pattern, ",") {
if match, err := filepath.Match(strings.TrimSpace(p), name); err == nil && match {
filePath = Abs(filePath)
if filePath != "" {
list = append(list, filePath)
}
}
}
}
return list, nil
}

40
g/os/gfile/gfile_sort.go Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gfile
import (
"strings"
"github.com/gogf/gf/g/container/garray"
)
// fileSortFunc is the comparison function for files.
// It sorts the array in order of: directory -> file.
// If <path1> and <path2> are the same type, it then sorts them as strings.
func fileSortFunc(path1, path2 string) int {
isDirPath1 := IsDir(path1)
isDirPath2 := IsDir(path2)
if isDirPath1 && !isDirPath2 {
return -1
}
if !isDirPath1 && isDirPath2 {
return 1
}
if n := strings.Compare(path1, path2); n != 0 {
return n
} else {
return -1
}
}
// SortFiles sorts the <files> in order of: directory -> file.
// Note that the item of <files> should be absolute path.
func SortFiles(files []string) []string {
array := garray.NewSortedStringArrayComparator(fileSortFunc)
array.Add(files...)
return array.Slice()
}

View File

@ -0,0 +1,77 @@
// Copyright 2017-2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gfile
import (
"os"
"runtime"
"github.com/gogf/gf/g/internal/debug"
"github.com/gogf/gf/g/text/gregex"
"github.com/gogf/gf/g/text/gstr"
)
const (
gPATH_FILTER_KEY = "/g/os/gfile/gfile_source.go"
)
// SourcePath returns absolute file path of the current source file path.
//
// Note that it's only available in develop environment.
func SourcePath(skip ...int) string {
path, _ := debug.CallerWithFilter(gPATH_FILTER_KEY, skip...)
return path
}
// MainPkgPath returns absolute file path of package main,
// which contains the entrance function main.
//
// It's only available in develop environment.
//
// Note1: Only valid for source development environments,
// IE only valid for systems that generate this executable.
//
// Note2: When the method is called for the first time, if it is in an asynchronous goroutine,
// the method may not get the main package path.
func MainPkgPath() string {
path := mainPkgPath.Val()
if path != "" {
if path == "-" {
return ""
}
return path
}
for i := 1; i < 10000; i++ {
if _, file, _, ok := runtime.Caller(i); ok {
// <file> is separated by '/'
if gstr.Contains(file, "/gf/g/") {
continue
}
if Ext(file) != ".go" {
continue
}
// separator of <file> '/' will be converted to Separator.
for path = Dir(file); len(path) > 1 && Exists(path) && path[len(path)-1] != os.PathSeparator; {
files, _ := ScanDir(path, "*.go")
for _, v := range files {
if gregex.IsMatchString(`package\s+main`, GetContents(v)) {
mainPkgPath.Set(path)
return path
}
}
path = Dir(path)
}
} else {
break
}
}
// If it fails finding the path, then mark it as "-",
// which means it will never do this search again.
mainPkgPath.Set("-")
return ""
}

View File

@ -1,13 +1,14 @@
package gfile_test
import (
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
)
// 创建测试文件
@ -50,7 +51,7 @@ func testpath() string {
return os.TempDir()
}
func TestGetContents(t *testing.T) {
func Test_GetContents(t *testing.T) {
gtest.Case(t, func() {
var (
@ -65,7 +66,7 @@ func TestGetContents(t *testing.T) {
})
}
func TestGetBinContents(t *testing.T) {
func Test_GetBinContents(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths1 string = "/testfile_t1.txt" // 文件存在时
@ -87,7 +88,7 @@ func TestGetBinContents(t *testing.T) {
}
// 截断文件为指定的大小
func TestTruncate(t *testing.T) {
func Test_Truncate(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths1 string = "/testfile_GetContentsyyui.txt" //文件存在时
@ -114,7 +115,7 @@ func TestTruncate(t *testing.T) {
})
}
func TestPutContents(t *testing.T) {
func Test_PutContents(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths string = "/testfile_PutContents.txt"
@ -138,7 +139,7 @@ func TestPutContents(t *testing.T) {
})
}
func TestPutContentsAppend(t *testing.T) {
func Test_PutContentsAppend(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths string = "/testfile_PutContents.txt"
@ -163,7 +164,7 @@ func TestPutContentsAppend(t *testing.T) {
}
func TestPutBinContents(t *testing.T) {
func Test_PutBinContents(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths string = "/testfile_PutContents.txt"
@ -187,7 +188,7 @@ func TestPutBinContents(t *testing.T) {
})
}
func TestPutBinContentsAppend(t *testing.T) {
func Test_PutBinContentsAppend(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths string = "/testfile_PutContents.txt" //原文件内容: yy
@ -210,7 +211,7 @@ func TestPutBinContentsAppend(t *testing.T) {
})
}
func TestGetBinContentsByTwoOffsetsByPath(t *testing.T) {
func Test_GetBinContentsByTwoOffsetsByPath(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths string = "/testfile_GetContents.txt" // 文件内容: abcdefghijk
@ -230,7 +231,7 @@ func TestGetBinContentsByTwoOffsetsByPath(t *testing.T) {
}
func TestGetNextCharOffsetByPath(t *testing.T) {
func Test_GetNextCharOffsetByPath(t *testing.T) {
gtest.Case(t, func() {
var (
filepaths string = "/testfile_GetContents.txt" // 文件内容: abcdefghijk
@ -247,7 +248,7 @@ func TestGetNextCharOffsetByPath(t *testing.T) {
})
}
func TestGetNextCharOffset(t *testing.T) {
func Test_GetNextCharOffset(t *testing.T) {
gtest.Case(t, func() {
var (
localindex int64
@ -263,7 +264,7 @@ func TestGetNextCharOffset(t *testing.T) {
})
}
func TestGetBinContentsByTwoOffsets(t *testing.T) {
func Test_GetBinContentsByTwoOffsets(t *testing.T) {
gtest.Case(t, func() {
var (
reads []byte
@ -279,7 +280,7 @@ func TestGetBinContentsByTwoOffsets(t *testing.T) {
})
}
func TestGetBinContentsTilChar(t *testing.T) {
func Test_GetBinContentsTilChar(t *testing.T) {
gtest.Case(t, func() {
var (
reads []byte
@ -296,7 +297,7 @@ func TestGetBinContentsTilChar(t *testing.T) {
})
}
func TestGetBinContentsTilCharByPath(t *testing.T) {
func Test_GetBinContentsTilCharByPath(t *testing.T) {
gtest.Case(t, func() {
var (
reads []byte
@ -319,7 +320,7 @@ func TestGetBinContentsTilCharByPath(t *testing.T) {
})
}
func TestHome(t *testing.T) {
func Test_Home(t *testing.T) {
gtest.Case(t, func() {
var (
reads string

View File

@ -0,0 +1,28 @@
package gfile_test
import (
"testing"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
)
func Test_Scan(t *testing.T) {
teatPath := gfile.Dir(gfile.SourcePath()) + gfile.Separator + "testdata"
gtest.Case(t, func() {
files, err := gfile.ScanDir(teatPath, "*", false)
gtest.Assert(err, nil)
gtest.AssertIN(teatPath+gfile.Separator+"dir1", files)
gtest.AssertIN(teatPath+gfile.Separator+"dir2", files)
gtest.AssertNE(teatPath+gfile.Separator+"dir1"+gfile.Separator+"file1", files)
})
gtest.Case(t, func() {
files, err := gfile.ScanDir(teatPath, "*", true)
gtest.Assert(err, nil)
gtest.AssertNE(teatPath+gfile.Separator+"dir1", files)
gtest.AssertNE(teatPath+gfile.Separator+"dir2", files)
gtest.AssertIN(teatPath+gfile.Separator+"dir1"+gfile.Separator+"file1", files)
gtest.AssertIN(teatPath+gfile.Separator+"dir2"+gfile.Separator+"file2", files)
})
}

View File

@ -1,13 +1,14 @@
package gfile_test
import (
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
"path/filepath"
"testing"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
)
func TestSearch(t *testing.T) {
func Test_Search(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfiless"

View File

@ -1,12 +1,13 @@
package gfile_test
import (
"testing"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
"testing"
)
func TestSize(t *testing.T) {
func Test_Size(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfile_t1.txt"
@ -25,7 +26,7 @@ func TestSize(t *testing.T) {
})
}
func TestFormatSize(t *testing.T) {
func Test_FormatSize(t *testing.T) {
gtest.Case(t, func() {
gtest.Assert(gfile.FormatSize(0), "0.00B")
gtest.Assert(gfile.FormatSize(16), "16.00B")
@ -38,13 +39,10 @@ func TestFormatSize(t *testing.T) {
gtest.Assert(gfile.FormatSize(9600000000000), "8.73T")
gtest.Assert(gfile.FormatSize(9600000000000000), "8.53P")
gtest.Assert(gfile.FormatSize(9600000000000000000), "TooLarge")
})
}
func TestReadableSize(t *testing.T) {
func Test_ReadableSize(t *testing.T) {
gtest.Case(t, func() {
var (

View File

@ -10,7 +10,7 @@ import (
"github.com/gogf/gf/g/test/gtest"
)
func TestIsDir(t *testing.T) {
func Test_IsDir(t *testing.T) {
gtest.Case(t, func() {
paths := "/testfile"
@ -26,7 +26,7 @@ func TestIsDir(t *testing.T) {
}
func TestCreate(t *testing.T) {
func Test_Create(t *testing.T) {
gtest.Case(t, func() {
var (
err error
@ -49,7 +49,7 @@ func TestCreate(t *testing.T) {
}
func TestOpen(t *testing.T) {
func Test_Open(t *testing.T) {
gtest.Case(t, func() {
var (
err error
@ -82,7 +82,7 @@ func TestOpen(t *testing.T) {
})
}
func TestOpenFile(t *testing.T) {
func Test_OpenFile(t *testing.T) {
gtest.Case(t, func() {
var (
err error
@ -115,7 +115,7 @@ func TestOpenFile(t *testing.T) {
})
}
func TestOpenWithFlag(t *testing.T) {
func Test_OpenWithFlag(t *testing.T) {
gtest.Case(t, func() {
var (
err error
@ -147,7 +147,7 @@ func TestOpenWithFlag(t *testing.T) {
})
}
func TestOpenWithFlagPerm(t *testing.T) {
func Test_OpenWithFlagPerm(t *testing.T) {
gtest.Case(t, func() {
var (
err error
@ -178,7 +178,7 @@ func TestOpenWithFlagPerm(t *testing.T) {
})
}
func TestExists(t *testing.T) {
func Test_Exists(t *testing.T) {
gtest.Case(t, func() {
var (
@ -210,7 +210,7 @@ func TestExists(t *testing.T) {
})
}
func TestPwd(t *testing.T) {
func Test_Pwd(t *testing.T) {
gtest.Case(t, func() {
paths, err := os.Getwd()
gtest.Assert(err, nil)
@ -219,7 +219,7 @@ func TestPwd(t *testing.T) {
})
}
func TestIsFile(t *testing.T) {
func Test_IsFile(t *testing.T) {
gtest.Case(t, func() {
var (
flag bool
@ -255,7 +255,7 @@ func TestIsFile(t *testing.T) {
})
}
func TestInfo(t *testing.T) {
func Test_Info(t *testing.T) {
gtest.Case(t, func() {
var (
err error
@ -277,7 +277,7 @@ func TestInfo(t *testing.T) {
})
}
func TestMove(t *testing.T) {
func Test_Move(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/ovetest"
@ -301,7 +301,7 @@ func TestMove(t *testing.T) {
})
}
func TestRename(t *testing.T) {
func Test_Rename(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/testfiles"
@ -324,7 +324,7 @@ func TestRename(t *testing.T) {
}
func TestCopy(t *testing.T) {
func Test_Copy(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/testfile_copyfile1.txt"
@ -342,7 +342,7 @@ func TestCopy(t *testing.T) {
})
}
func TestDirNames(t *testing.T) {
func Test_DirNames(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/testdirs"
@ -372,7 +372,7 @@ func TestDirNames(t *testing.T) {
})
}
func TestGlob(t *testing.T) {
func Test_Glob(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/testfiles/*.txt"
@ -413,7 +413,7 @@ func TestGlob(t *testing.T) {
})
}
func TestRemove(t *testing.T) {
func Test_Remove(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/testfile_t1.txt"
@ -428,7 +428,7 @@ func TestRemove(t *testing.T) {
})
}
func TestIsReadable(t *testing.T) {
func Test_IsReadable(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfile_GetContents.txt"
@ -444,7 +444,7 @@ func TestIsReadable(t *testing.T) {
})
}
func TestIsWritable(t *testing.T) {
func Test_IsWritable(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfile_GetContents.txt"
@ -459,7 +459,7 @@ func TestIsWritable(t *testing.T) {
})
}
func TestChmod(t *testing.T) {
func Test_Chmod(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfile_GetContents.txt"
@ -474,7 +474,7 @@ func TestChmod(t *testing.T) {
})
}
func TestScanDir(t *testing.T) {
func Test_ScanDir(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfiledirs"
@ -505,7 +505,7 @@ func TestScanDir(t *testing.T) {
}
// 获取绝对目录地址
func TestRealPath(t *testing.T) {
func Test_RealPath(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfile_files"
@ -529,7 +529,7 @@ func TestRealPath(t *testing.T) {
}
// 获取当前执行文件的目录
func TestSelfPath(t *testing.T) {
func Test_SelfPath(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string
@ -548,7 +548,7 @@ func TestSelfPath(t *testing.T) {
})
}
func TestSelfDir(t *testing.T) {
func Test_SelfDir(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string
@ -565,7 +565,7 @@ func TestSelfDir(t *testing.T) {
})
}
func TestBasename(t *testing.T) {
func Test_Basename(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfilerr_GetContents.txt"
@ -581,7 +581,7 @@ func TestBasename(t *testing.T) {
})
}
func TestDir(t *testing.T) {
func Test_Dir(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfiless"
@ -598,7 +598,7 @@ func TestDir(t *testing.T) {
}
// 获取文件名
func TestExt(t *testing.T) {
func Test_Ext(t *testing.T) {
gtest.Case(t, func() {
var (
paths1 string = "/testfile_GetContents.txt"
@ -616,7 +616,7 @@ func TestExt(t *testing.T) {
})
}
func TestTempDir(t *testing.T) {
func Test_TempDir(t *testing.T) {
gtest.Case(t, func() {
var (
tpath string
@ -628,7 +628,7 @@ func TestTempDir(t *testing.T) {
})
}
func TestMkdir(t *testing.T) {
func Test_Mkdir(t *testing.T) {
gtest.Case(t, func() {
var (
tpath string = "/testfile/createdir"
@ -649,7 +649,7 @@ func TestMkdir(t *testing.T) {
})
}
func TestStat(t *testing.T) {
func Test_Stat(t *testing.T) {
gtest.Case(t, func() {
var (
tpath1 = "/testfile_t1.txt"
@ -672,14 +672,14 @@ func TestStat(t *testing.T) {
})
}
func TestMainPkgPath(t *testing.T) {
func Test_MainPkgPath(t *testing.T) {
gtest.Case(t, func() {
reads := gfile.MainPkgPath()
gtest.Assert(reads, "")
})
}
func TestCopyFile(t *testing.T) {
func Test_CopyFile(t *testing.T) {
gtest.Case(t, func() {
var (
paths string = "/testfile_copyfile1.txt"
@ -697,7 +697,7 @@ func TestCopyFile(t *testing.T) {
})
}
func TestCopyDir(t *testing.T) {
func Test_CopyDir(t *testing.T) {
gtest.Case(t, func() {
var (
dirpath1 string = "/testcopydir1"

View File

@ -1,13 +1,14 @@
package gfile_test
import (
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
"os"
"testing"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/test/gtest"
)
func TestMTime(t *testing.T) {
func Test_MTime(t *testing.T) {
gtest.Case(t, func() {
var (
@ -26,7 +27,7 @@ func TestMTime(t *testing.T) {
})
}
func TestMTimeMillisecond(t *testing.T) {
func Test_MTimeMillisecond(t *testing.T) {
gtest.Case(t, func() {
var (
file1 string = "/testfile_t1.txt"

0
g/os/gfile/testdata/dir1/file1 vendored Normal file
View File

0
g/os/gfile/testdata/dir2/file2 vendored Normal file
View File

View File

@ -244,10 +244,12 @@ func (l *Logger) print(std io.Writer, lead string, value ...interface{}) {
// Caller path.
callerPath := ""
if l.flags&F_FILE_LONG > 0 {
callerPath = debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip) + ": "
path, line := debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip)
callerPath = fmt.Sprintf(`%s:%d: `, path, line)
}
if l.flags&F_FILE_SHORT > 0 {
callerPath = gfile.Basename(debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip)) + ": "
path, line := debug.CallerWithFilter(gPATH_FILTER_KEY, l.stSkip)
callerPath = fmt.Sprintf(`%s:%d: `, gfile.Basename(path), line)
}
if len(callerPath) > 0 {
buffer.WriteString(callerPath)

View File

@ -6,6 +6,6 @@ import (
)
func main() {
gutil.Dump(gfile.ScanDir("/home/john/Documents", "*"))
gutil.Dump(gfile.ScanDir("/Users/john/Documents", "*.*"))
gutil.Dump(gfile.ScanDir("/home/john/temp/newproject", "*", true))
}

View File

@ -1,10 +1,5 @@
package main
import (
"fmt"
"path/filepath"
)
func main() {
fmt.Println(filepath.Abs("s/s/s/s/s"))
}