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
|
||
}
|