/
file.go
152 lines (137 loc) · 4.21 KB
/
file.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package upload
import (
"github.com/limitcool/blog/global"
"github.com/limitcool/blog/internal/util"
"io"
"io/ioutil"
"log"
"mime/multipart"
"os"
"path"
"strings"
)
type FileType int
const (
TypeImage FileType = iota + 1
TypeMarkdown
TypeExcel
TypeTxt
)
// GetFileName 获取文件名称,先是通过获取文件后缀并筛出原始文件名进行 MD5 加密,最后返回经过加密处理后的文件名。
func GetFileName(name string) string {
ext := GetFileExt(name)
for _, markdownExt := range global.AppSetting.UploadMarkdownAllowExts {
if strings.ToUpper(markdownExt) == strings.ToUpper(ext) {
return name
}
}
fileName := strings.TrimSuffix(name, ext)
fileName = util.Md5(fileName)
return fileName + ext
}
func IsMarkdownExist(name string) bool {
files, err := ioutil.ReadDir("storage/uploads/markdown")
if err != nil {
log.Fatal(err)
}
for _, f := range files {
if f.Name() == name {
return true
}
}
return false
}
// GetFileExt 获取文件后缀,主要是通过调用 path.Ext 方法进行循环查找”.“符号,最后通过切片索引返回对应的文化后缀名称。
func GetFileExt(name string) string {
return path.Ext(name)
}
// GetSavePath 获取文件保存地址,这里直接返回配置中的文件保存目录即可,也便于后续的调整。
func GetSavePath(t FileType) string {
switch t {
case TypeImage:
return global.AppSetting.UploadSavePath + "/images"
case TypeMarkdown:
return global.AppSetting.UploadSavePath + "/markdown"
default:
return global.AppSetting.UploadSavePath
}
}
// GetUrlSavePath 获取文件保存URl,这里直接返回URL
func GetUrlSavePath(t FileType) string {
switch t {
case TypeImage:
return global.AppSetting.UploadServerUrl + "/images"
case TypeMarkdown:
return global.AppSetting.UploadServerUrl + "/markdown"
default:
return global.AppSetting.UploadServerUrl
}
}
// CheckSavePath 检查保存目录是否存在,通过调用 os.Stat 方法获取文件的描述信息 FileInfo,并调用 os.IsNotExist 方法进行判断,其原理是利用 os.Stat 方法所返回的 error 值与系统中所定义的 oserror.ErrNotExist 进行判断,以此达到校验效果
func CheckSavePath(dst string) bool {
_, err := os.Stat(dst)
return os.IsExist(err)
}
func CheckContainExt(t FileType, name string) bool {
ext := GetFileExt(name)
ext = strings.ToUpper(ext)
switch t {
case TypeImage:
for _, allowExt := range global.AppSetting.UploadImageAllowExts {
if strings.ToUpper(allowExt) == ext {
return true
}
}
case TypeMarkdown:
for _, allowExt := range global.AppSetting.UploadMarkdownAllowExts {
if strings.ToUpper(allowExt) == ext {
return true
}
}
}
return false
}
// CheckMaxsize 检查文件大小是否超出最大大小限制。
func CheckMaxsize(t FileType, f multipart.File) bool {
content, _ := ioutil.ReadAll(f)
size := len(content)
switch t {
case TypeImage:
if size >= global.AppSetting.UploadImageMaxSize*1024*1024 {
return false
}
case TypeMarkdown:
if size >= global.AppSetting.UploadImageMaxSize*1024*1024 {
return false
}
}
return true
}
// CheckPermission 检查文件权限是否足够,与 CheckSavePath 方法原理一致,是利用 oserror.ErrPermission 进行判断。
func CheckPermission(dst string) bool {
_, err := os.Stat(dst)
return os.IsPermission(err)
}
// CreateSavePath 创建在上传文件时所使用的保存目录,在方法内部调用的 os.MkdirAll 方法,该方法将会以传入的 os.FileMode 权限位去递归创建所需的所有目录结构,若涉及的目录均已存在,则不会进行任何操作,直接返回 nil。
func CreateSavePath(dst string, perm os.FileMode) error {
err := os.MkdirAll(dst, perm)
if err != nil {
return err
}
return nil
}
// SavaFile 保存所上传的文件,该方法主要是通过调用 os.Create 方法创建目标地址的文件,再通过 file.Open 方法打开源地址的文件,结合 io.Copy 方法实现两者之间的文件内容拷贝
func SavaFile(file *multipart.FileHeader, dst string) error {
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, src)
return err
}