mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
Merge branch 'v2' of github.com:duke-git/lancet into v2
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CreateDir](#CreateDir)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [CopyDir](#CopyDir)
|
||||
- [CurrentPath](#CurrentPath)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
@@ -162,6 +163,34 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CopyDir">CopyDir</span>
|
||||
|
||||
<p>拷贝文件夹到目标路径,会递归复制文件夹下所有的文件及文件夹,并且访问权限也与源文件夹保持一致。当dstPath存在时会返回error</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func CopyDir(srcPath string, dstPath string) error
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/YAyFTA_UuPb)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.CopyFile("./test_src", "./test_dest")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CurrentPath">CurrentPath</span>
|
||||
|
||||
<p>返回当前位置的绝对路径。</p>
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
- [CreateFile](#CreateFile)
|
||||
- [CreateDir](#CreateDir)
|
||||
- [CopyFile](#CopyFile)
|
||||
- [CopyDir](#CopyDir)
|
||||
- [CurrentPath](#CurrentPath)
|
||||
- [FileMode](#FileMode)
|
||||
- [MiMeType](#MiMeType)
|
||||
@@ -162,6 +163,34 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CopyDir">CopyDir</span>
|
||||
|
||||
<p>copy src directory to dst directory, it will copy all files and directories recursively. the access permission will be the same as the source directory. if dstPath exists, it will return an error.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func CopyDir(srcPath string, dstPath string) error
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/YAyFTA_UuPb)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := fileutil.CopyFile("./test_src", "./test_dest")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="CurrentPath">CurrentPath</span>
|
||||
|
||||
<p>return current absolute path.</p>
|
||||
|
||||
@@ -113,6 +113,65 @@ func CreateDir(absPath string) error {
|
||||
return os.MkdirAll(absPath, os.ModePerm)
|
||||
}
|
||||
|
||||
// CopyDir copy src directory to dst directory, it will copy all files and directories recursively.
|
||||
// the access permission will be the same as the source directory.
|
||||
// if dstPath exists, it will return an error.
|
||||
// Play: https://go.dev/play/p/YAyFTA_UuPb
|
||||
func CopyDir(srcPath string, dstPath string) error {
|
||||
if !IsDir(srcPath) {
|
||||
return errors.New("source path is not a directory")
|
||||
}
|
||||
var err error
|
||||
srcPath, err = filepath.Abs(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if IsExist(dstPath) {
|
||||
return errors.New("destination path already exists")
|
||||
}
|
||||
dstPath, err = filepath.Abs(dstPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get srcPath's file info
|
||||
srcFileInfo, err := os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create dstPath with srcPath's mode
|
||||
err = os.MkdirAll(dstPath, srcFileInfo.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = filepath.Walk(srcPath, func(path string, info os.FileInfo, err error) error {
|
||||
if srcPath == path {
|
||||
return nil
|
||||
}
|
||||
curDstPath := filepath.Join(dstPath, filepath.Base(path))
|
||||
if info.IsDir() {
|
||||
err = CopyDir(path, curDstPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = CopyFile(path, curDstPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Chmod(curDstPath, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// IsDir checks if the path is directory or not.
|
||||
// Play: https://go.dev/play/p/WkVwEKqtOWk
|
||||
func IsDir(path string) bool {
|
||||
@@ -377,7 +436,7 @@ func UnZip(zipFile string, destPath string) error {
|
||||
defer zipReader.Close()
|
||||
|
||||
for _, f := range zipReader.File {
|
||||
//issue#62: fix ZipSlip bug
|
||||
// issue#62: fix ZipSlip bug
|
||||
path, err := safeFilepathJoin(destPath, f.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -3,6 +3,8 @@ package fileutil
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
@@ -544,3 +546,23 @@ func TestReadlineFile(t *testing.T) {
|
||||
internal.NewAssert(t, "TestReadlineFile").Equal(line, lineRead)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyDir(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCopyDir")
|
||||
|
||||
src := "./testdata"
|
||||
dest := "./testdata_copy"
|
||||
|
||||
err := CopyDir(src, dest)
|
||||
assert.IsNil(err)
|
||||
|
||||
assert.Equal(true, IsExist(dest))
|
||||
|
||||
filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
|
||||
destPath := strings.Replace(path, src, dest, 1)
|
||||
assert.Equal(true, IsExist(destPath))
|
||||
return nil
|
||||
})
|
||||
|
||||
os.RemoveAll(dest)
|
||||
}
|
||||
|
||||
1
fileutil/testdata/test01/demo2.csv
vendored
Normal file
1
fileutil/testdata/test01/demo2.csv
vendored
Normal file
@@ -0,0 +1 @@
|
||||
makj1
|
||||
|
0
test_src/test.txt01
Normal file
0
test_src/test.txt01
Normal file
0
test_src/test.txt02
Normal file
0
test_src/test.txt02
Normal file
Reference in New Issue
Block a user