474 lines
13 KiB
Go
474 lines
13 KiB
Go
|
package coryCommon
|
|||
|
|
|||
|
import (
|
|||
|
"bufio"
|
|||
|
"context"
|
|||
|
"fmt"
|
|||
|
"io"
|
|||
|
"log"
|
|||
|
"net/url"
|
|||
|
"os"
|
|||
|
"path/filepath"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
|
|||
|
"github.com/gogf/gf/v2/net/ghttp"
|
|||
|
"github.com/tiger1103/gfast/v3/library/liberr"
|
|||
|
"golang.org/x/exp/rand"
|
|||
|
)
|
|||
|
|
|||
|
func UploadFileS(ctx context.Context, fileHeader []*ghttp.UploadFile, fileUrl string, typeStr string) (pathStr string, err error) {
|
|||
|
for i := range fileHeader {
|
|||
|
var str string
|
|||
|
if typeStr == "1" {
|
|||
|
str, err = UploadFile(ctx, fileHeader[i], fileUrl)
|
|||
|
}
|
|||
|
if typeStr == "2" {
|
|||
|
str, err = UploadFileTwo(ctx, fileHeader[i], fileUrl)
|
|||
|
}
|
|||
|
if err != nil {
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return
|
|||
|
}
|
|||
|
pathStr = pathStr + ResourcePublicToFunc("/"+str, 0) + ","
|
|||
|
}
|
|||
|
pathStr = pathStr[0 : len(pathStr)-1]
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// UploadFile [文件名称为原来的文件名称] 上传文件(流) 也可以将http图片上传 返回:resource/public/upload_file/2023-11-28/tmp_c7858f0fd98d74cbe2c095125871aaf19c749c209ae33f5f.png
|
|||
|
func UploadFile(ctx context.Context, fileHeader *ghttp.UploadFile, fileUrl string) (str string, err error) {
|
|||
|
// 获取上传的文件流
|
|||
|
if fileHeader == nil {
|
|||
|
log.Println("Failed to get file")
|
|||
|
liberr.ErrIsNil(ctx, err, "Failed to get file")
|
|||
|
return "", err
|
|||
|
}
|
|||
|
ynr := Ynr(fileUrl)
|
|||
|
// 在当前目录创建一个新文件用于保存上传的数据
|
|||
|
lj := "/" + ynr + fileHeader.Filename
|
|||
|
destFilePath := filepath.Join(".", lj)
|
|||
|
destFile, err := os.Create(destFilePath)
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to create destination file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer destFile.Close()
|
|||
|
|
|||
|
// 创建一个内存缓冲区作为文件数据的临时存储
|
|||
|
buffer := make([]byte, 4096)
|
|||
|
|
|||
|
// 记录已接收的数据量,用于计算上传进度
|
|||
|
var totalReceived int64
|
|||
|
|
|||
|
// 获取文件上传的数据流
|
|||
|
file, err := fileHeader.Open()
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to open file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer file.Close()
|
|||
|
|
|||
|
// 循环读取文件流,直到读取完整个文件
|
|||
|
for {
|
|||
|
// 从文件流中读取数据到缓冲区
|
|||
|
n, err := file.Read(buffer)
|
|||
|
if err != nil && err != io.EOF {
|
|||
|
log.Println("Failed to read file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 如果缓冲区没有数据,则表示已读取完整个文件
|
|||
|
if n == 0 {
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
// 将缓冲区的数据写入目标文件
|
|||
|
_, err = destFile.Write(buffer[:n])
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to write file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 更新已接收的数据量
|
|||
|
totalReceived += int64(n)
|
|||
|
}
|
|||
|
|
|||
|
//// 返回上传文件的路径给客户端
|
|||
|
//uploadPath, err := filepath.Abs(destFilePath)
|
|||
|
//if err != nil {
|
|||
|
// log.Println("Failed to get absolute file path:", err)
|
|||
|
// liberr.ErrIsNil(ctx, err)
|
|||
|
// return "", err
|
|||
|
//}
|
|||
|
//统一路径斜杠为/
|
|||
|
str = filepath.ToSlash(lj)
|
|||
|
return str, err
|
|||
|
}
|
|||
|
|
|||
|
func UploadUniqueFile(ctx context.Context, fileHeader *ghttp.UploadFile, fileUrl string) (str string, err error) {
|
|||
|
// 获取上传的文件流
|
|||
|
if fileHeader == nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
ynr := Ynr(fileUrl)
|
|||
|
|
|||
|
// 在当前目录创建一个新文件用于保存上传的数据
|
|||
|
// 在文件名中添加一个唯一的标识符,例如当前的时间戳
|
|||
|
lj := fmt.Sprintf("%s_%d_%s", ynr, time.Now().Unix(), fileHeader.Filename)
|
|||
|
destFilePath := filepath.Join(".", lj)
|
|||
|
destFile, err := os.Create(destFilePath)
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to create destination file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer destFile.Close()
|
|||
|
|
|||
|
// 创建一个内存缓冲区作为文件数据的临时存储
|
|||
|
buffer := make([]byte, 4096)
|
|||
|
|
|||
|
// 记录已接收的数据量,用于计算上传进度
|
|||
|
var totalReceived int64
|
|||
|
|
|||
|
// 获取文件上传的数据流
|
|||
|
file, err := fileHeader.Open()
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to open file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer file.Close()
|
|||
|
|
|||
|
// 循环读取文件流,直到读取完整个文件
|
|||
|
for {
|
|||
|
// 从文件流中读取数据到缓冲区
|
|||
|
n, err := file.Read(buffer)
|
|||
|
if err != nil && err != io.EOF {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 如果缓冲区没有数据,则表示已读取完整个文件
|
|||
|
if n == 0 {
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
// 将缓冲区的数据写入目标文件
|
|||
|
_, err = destFile.Write(buffer[:n])
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 更新已接收的数据量
|
|||
|
totalReceived += int64(n)
|
|||
|
}
|
|||
|
|
|||
|
// 统一路径斜杠为/
|
|||
|
str = filepath.ToSlash(lj)
|
|||
|
return str, err
|
|||
|
}
|
|||
|
|
|||
|
// UploadFileTwo [文件名称为时间戳] 上传文件(流) 也可以将http图片上传 返回:resource/public/upload_file/2023-11-28/tmp_c7858f0fd98d74cbe2c095125871aaf19c749c209ae33f5f.png
|
|||
|
func UploadFileTwo(ctx context.Context, fileHeader *ghttp.UploadFile, fileUrl string) (str string, err error) {
|
|||
|
// 获取上传的文件流
|
|||
|
if fileHeader == nil {
|
|||
|
log.Println("Failed to get file")
|
|||
|
liberr.ErrIsNil(ctx, err, "Failed to get file")
|
|||
|
return "", err
|
|||
|
}
|
|||
|
ynr := Ynr(fileUrl)
|
|||
|
// 在当前目录创建一个新文件用于保存上传的数据
|
|||
|
lj := /* "/" +*/ ynr + FileName("login") + filepath.Ext(fileHeader.Filename)
|
|||
|
|
|||
|
destFilePath := filepath.Join(".", lj)
|
|||
|
destFile, err := os.Create(destFilePath)
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to create destination file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer destFile.Close()
|
|||
|
|
|||
|
// 创建一个内存缓冲区作为文件数据的临时存储
|
|||
|
buffer := make([]byte, 4096)
|
|||
|
|
|||
|
// 记录已接收的数据量,用于计算上传进度
|
|||
|
var totalReceived int64
|
|||
|
|
|||
|
// 获取文件上传的数据流
|
|||
|
file, err := fileHeader.Open()
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to open file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
defer file.Close()
|
|||
|
|
|||
|
// 循环读取文件流,直到读取完整个文件
|
|||
|
for {
|
|||
|
// 从文件流中读取数据到缓冲区
|
|||
|
n, err := file.Read(buffer)
|
|||
|
if err != nil && err != io.EOF {
|
|||
|
log.Println("Failed to read file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 如果缓冲区没有数据,则表示已读取完整个文件
|
|||
|
if n == 0 {
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
// 将缓冲区的数据写入目标文件
|
|||
|
_, err = destFile.Write(buffer[:n])
|
|||
|
if err != nil {
|
|||
|
log.Println("Failed to write file:", err)
|
|||
|
liberr.ErrIsNil(ctx, err)
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
// 更新已接收的数据量
|
|||
|
totalReceived += int64(n)
|
|||
|
}
|
|||
|
|
|||
|
//// 返回上传文件的路径给客户端
|
|||
|
//uploadPath, err := filepath.Abs(destFilePath)
|
|||
|
//if err != nil {
|
|||
|
// log.Println("Failed to get absolute file path:", err)
|
|||
|
// liberr.ErrIsNil(ctx, err)
|
|||
|
// return "", err
|
|||
|
//}
|
|||
|
//统一路径斜杠为/
|
|||
|
str = filepath.ToSlash(lj)
|
|||
|
return str, err
|
|||
|
}
|
|||
|
|
|||
|
// Ynr 创建时间文件夹 传递相对路径/resource/public/ 返回相对路径resource/public/2023-11-12/
|
|||
|
func Ynr(baseDir string) (str string) {
|
|||
|
// 获取当前时间
|
|||
|
currentTime := time.Now()
|
|||
|
// 格式化为年月日的字符串格式
|
|||
|
dateString := currentTime.Format("2006-01-02")
|
|||
|
dateString = baseDir + dateString
|
|||
|
// 在相对路径上添加文件夹
|
|||
|
destFilePath := filepath.Join(".", dateString)
|
|||
|
dateString = destFilePath
|
|||
|
// 检查文件夹是否已存在
|
|||
|
_, err := os.Stat(dateString)
|
|||
|
if os.IsNotExist(err) {
|
|||
|
// 文件夹不存在,创建文件夹
|
|||
|
err := os.MkdirAll(dateString, os.ModePerm)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("创建文件夹失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
// fmt.Println("文件夹创建成功:", dateString)
|
|||
|
} else {
|
|||
|
// fmt.Println("文件夹已存在:", dateString)
|
|||
|
}
|
|||
|
return dateString + "/"
|
|||
|
}
|
|||
|
|
|||
|
// FileName 【前缀】+获取当前时间+随机数得到文件名
|
|||
|
func FileName(prefix string) (uniqueFileName string) {
|
|||
|
currentTime := time.Now()
|
|||
|
timestamp := currentTime.UnixNano() / int64(time.Millisecond)
|
|||
|
randomNum := rand.Intn(1000)
|
|||
|
uniqueFileName = fmt.Sprintf("%d_%d", timestamp, randomNum)
|
|||
|
if prefix != "" {
|
|||
|
uniqueFileName = prefix + uniqueFileName
|
|||
|
}
|
|||
|
return uniqueFileName
|
|||
|
}
|
|||
|
|
|||
|
// FileInfo 传参:相对路径 获取文件信息(文件名称、文件后缀、文件大小(字节))
|
|||
|
func FileInfo(filePath string) (name string, ext string, size int64) {
|
|||
|
newPath := ""
|
|||
|
if strings.Contains(filePath, "wxfile") {
|
|||
|
newPath = strings.ReplaceAll(filePath, "/wxfile", GetCWD()+"/resource/public")
|
|||
|
} else {
|
|||
|
newPath = strings.ReplaceAll(filePath, "/file", GetCWD()+"/resource/public")
|
|||
|
}
|
|||
|
newPath = strings.ReplaceAll(newPath, "\\", "/")
|
|||
|
filePath = newPath
|
|||
|
// filePath = "D:\\Cory\\go\\中煤\\zmkg-back\\resource\\public\\upload_file\\2023-08-31\\cv6kxb89pd984rt5ze.png"
|
|||
|
// 获取文件的基本名称(包括扩展名)
|
|||
|
fileName := filepath.Base(filePath)
|
|||
|
// 分割文件名和扩展名
|
|||
|
nameParts := strings.Split(fileName, ".")
|
|||
|
fileNameWithoutExt := nameParts[0]
|
|||
|
fileExt := nameParts[1]
|
|||
|
// 获取文件大小
|
|||
|
fileInfo, err := os.Stat(filePath)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("无法获取文件信息:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
fileSize := fileInfo.Size()
|
|||
|
// 文件名称、文件后缀、文件大小(字节)
|
|||
|
name = fileNameWithoutExt
|
|||
|
ext = fileExt
|
|||
|
size = fileSize
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// OutJson 创建txt写入数据,jsonData数据、absPath 绝对路径(带文件名和后缀)
|
|||
|
func OutJson(jsonData []byte, absPath string) (flag bool, err error) {
|
|||
|
absPath = strings.ReplaceAll(absPath, "\\", "/")
|
|||
|
absPath = strings.ReplaceAll(absPath, "/file", GetCWD()+"/resource/public")
|
|||
|
flag = false
|
|||
|
// 创建要写入的文件
|
|||
|
file, err := os.Create(absPath)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("无法创建文件:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
defer file.Close()
|
|||
|
// 将 JSON 数据写入文件
|
|||
|
_, err = file.Write(jsonData)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("无法写入文件:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
return true, err
|
|||
|
}
|
|||
|
|
|||
|
// PutJson 读取文件
|
|||
|
func PutJson(filePath string) (jsonData string, err error) {
|
|||
|
filePath = strings.ReplaceAll(filePath, "/file", GetCWD()+"/resource/public")
|
|||
|
filePath = strings.ReplaceAll(filePath, "\\", "/")
|
|||
|
// filePath := "relative/path/to/file.txt"
|
|||
|
file, err := os.Open(filePath)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("打开文件错误:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
defer file.Close()
|
|||
|
|
|||
|
scanner := bufio.NewScanner(file)
|
|||
|
// 设置一个足够大的缓冲区
|
|||
|
const maxScanTokenSize = 128 * 1024
|
|||
|
buf := make([]byte, maxScanTokenSize)
|
|||
|
scanner.Buffer(buf, maxScanTokenSize)
|
|||
|
|
|||
|
for scanner.Scan() {
|
|||
|
line := scanner.Text()
|
|||
|
jsonData = jsonData + line
|
|||
|
}
|
|||
|
if scanner.Err() != nil {
|
|||
|
fmt.Println("读取文件错误:", scanner.Err())
|
|||
|
err = scanner.Err()
|
|||
|
return
|
|||
|
}
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
BatchFile 批量刪除文件
|
|||
|
filePath 相对路径
|
|||
|
*/
|
|||
|
func BatchFile(filePath []string) {
|
|||
|
for _, data := range filePath {
|
|||
|
// if strings.Contains(data, "file") || strings.Contains(data, "wxfile"){
|
|||
|
newPath := ""
|
|||
|
if strings.Contains(data, "/file") {
|
|||
|
newPath = strings.Replace(data, "/file", GetCWD()+"/resource/public", 1)
|
|||
|
} else if strings.Contains(data, "/wxfile") {
|
|||
|
newPath = strings.Replace(data, "/wxfile", GetCWD()+"/resource/public", 1)
|
|||
|
}
|
|||
|
os.Remove(strings.ReplaceAll(newPath, "\\", "/"))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// FlagImg 判斷是否是圖片
|
|||
|
func FlagImg(filePath string) (flag bool) {
|
|||
|
filePathLower := strings.ToLower(filePath)
|
|||
|
isImage := strings.HasSuffix(filePathLower, ".png") || strings.HasSuffix(filePathLower, ".jpg") || strings.HasSuffix(filePathLower, ".jpeg") || strings.HasSuffix(filePathLower, ".gif") || strings.HasSuffix(filePathLower, ".bmp")
|
|||
|
if isImage {
|
|||
|
flag = true
|
|||
|
} else {
|
|||
|
flag = false
|
|||
|
}
|
|||
|
return flag
|
|||
|
}
|
|||
|
|
|||
|
// CreateDirectory 判断文件夹是否存在,不存在则创建文件夹
|
|||
|
func CreateDirectory(folderName string) error {
|
|||
|
// 检查文件夹是否已经存在
|
|||
|
_, err := os.Stat(folderName)
|
|||
|
if err == nil {
|
|||
|
return nil
|
|||
|
}
|
|||
|
// 创建文件夹
|
|||
|
err = os.Mkdir(folderName, 0o755)
|
|||
|
if err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
// FileToFunc file转resource/public
|
|||
|
func FileToFunc(path string, num int) (rpath string) {
|
|||
|
if num == 1 {
|
|||
|
rpath = strings.Replace(path, GetCWD()+"/file/", "/resource/public/", 1)
|
|||
|
} else if num == 2 {
|
|||
|
rpath = strings.Replace(path, "/file/", GetCWD()+"/resource/public/", 1)
|
|||
|
} else if num == 3 {
|
|||
|
rpath = strings.Replace(path, "/file/", "/wxfile/", 1)
|
|||
|
} else if num == 4 {
|
|||
|
rpath = strings.Replace(path, "/wxfile/", GetCWD()+"/resource/public/", 1)
|
|||
|
} else if num == 5 {
|
|||
|
rpath = strings.Replace(path, "/wxfile/", "/file/", 1)
|
|||
|
} else {
|
|||
|
rpath = strings.Replace(path, "/file/", "/resource/public/", 1)
|
|||
|
}
|
|||
|
rpath = filepath.ToSlash(rpath)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// ResourcePublicToFunc resource/public转file
|
|||
|
func ResourcePublicToFunc(path string, num int) (rpath string) {
|
|||
|
if num == 1 {
|
|||
|
rpath = strings.Replace(path, GetCWD()+"/resource/public/", "/file/", 1)
|
|||
|
} else if num == 2 {
|
|||
|
rpath = strings.Replace(path, "/resource/public/", GetCWD()+"/resource/public/", 1)
|
|||
|
} else if num == 3 {
|
|||
|
rpath = strings.Replace(path, "/resource/public/", "/wxfile/", 1)
|
|||
|
} else {
|
|||
|
rpath = strings.Replace(path, "/resource/public/", "/file/", 1)
|
|||
|
}
|
|||
|
rpath = filepath.ToSlash(rpath)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// FormatRestrictionFunc 判断文件后缀是否匹配
|
|||
|
func FormatRestrictionFunc(path, suffix string) (flag bool) {
|
|||
|
split := strings.Split(suffix, ",")
|
|||
|
for _, data := range split {
|
|||
|
extension := filepath.Ext(path)
|
|||
|
if extension == data {
|
|||
|
return true
|
|||
|
}
|
|||
|
}
|
|||
|
return false
|
|||
|
}
|
|||
|
|
|||
|
// URLCoding 对url的特俗符号进行编码,不对/进行编码(定制编码,将"/file/networkDisk/completion/admin37/2.jpg"的"networkDisk/completion/admin37/2.jpg"进行编码)
|
|||
|
func URLCoding(path string) (filenPathCoding string) {
|
|||
|
s2 := path[6 : len(path)-1]
|
|||
|
split := strings.Split(s2, "/")
|
|||
|
p := ""
|
|||
|
for i2 := range split {
|
|||
|
p = p + url.PathEscape(split[i2]) + "/"
|
|||
|
}
|
|||
|
p = p[0 : len(p)-1]
|
|||
|
filenPathCoding = strings.ReplaceAll(path, s2, p)
|
|||
|
return
|
|||
|
}
|