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 }