-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathmain.go
204 lines (174 loc) · 6.04 KB
/
main.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// 用法展示
// 上传文件示例:go run main.go --action upload --uploadFilepaths /Users/haixian.luo/test/FtpData/data/abc.pdf
// 下载文件示例:go run main.go --action download --downloadDir /Users/haixian.luo/test/FtpData/download --downloadFilenames abc.pdf
// 列出文件示例:go run main.go --action list
package main
import (
"FtpClient/common"
"FtpClient/downloader"
"FtpClient/uploader"
"encoding/json"
"flag"
"fmt"
"net/http"
"os"
"strings"
"sync"
"time"
)
// 定义全局变量
var globalWait sync.WaitGroup // 等待多个文件上传或下载完
// 定义命令行参数对应的变量
var serverIP = flag.String("serverIP", "127.0.0.1", "服务IP")
var serverPort = flag.Int("serverPort", 800, "服务端口")
var action = flag.String("action", "", "upload, download or list")
var uploadFilepaths = flag.String("uploadFilepaths", "", "上传文件路径,多个文件路径用空格相隔")
var downloadFilenames = flag.String("downloadFilenames", "", "下载文件名")
var downloadDir = flag.String("downloadDir", "/data/lhx/FtpData/download", "下载路径,默认当前目录")
// 上传文件
func uploadFile(uploadFilepath string) {
defer globalWait.Done()
var err error = nil
// 获取文件大小,如果小于等于1M则整个文件上传,否则采用分片方式上传
filesize := common.GetFileSize(uploadFilepath)
if filesize <= common.SmallFileSize {
// 小文件
err = uploader.UploadFile(uploadFilepath)
} else {
// 大文件,进行切片上传
// 这里需要判断是否是上传到一半的文件,如果是则重新加载上传器,如果不是则重新创建上传器当新文件进行上传
uloader := uploader.GetUploader(uploadFilepath, common.SliceBytes)
if uloader == nil {
fmt.Println("这是一个全新要上传的文件")
uloader = uploader.NewUploader(uploadFilepath, common.SliceBytes)
}
if uloader == nil {
fmt.Println("创建上传器失败,上传文件失败")
return
}
// 切片方式进行文件上传
err = uloader.UploadFileBySlice()
}
if err != nil {
fmt.Printf("上传%s文件失败\n", uploadFilepath)
}
}
// 上传多个文件
func uploadFiles(uploadFilepaths string) {
// 以空格方式分割要上传的文件
files := strings.Split(uploadFilepaths, " ")
for _, file := range files {
globalWait.Add(1)
go uploadFile(file)
}
globalWait.Wait()
}
// 获取文件基本信息,用以判断是普通类型文件还是切片类型文件
func getFileInfo(filename string) (*common.FileInfo, error) {
targetUrl := common.BaseUrl + "getFileInfo?filename=" + filename
req, _ := http.NewRequest("GET", targetUrl, nil)
resp, err := (&http.Client{}).Do(req)
if err != nil {
fmt.Println(err)
return nil, err
}
defer resp.Body.Close()
var baseInfo common.FileInfo
err = json.NewDecoder(resp.Body).Decode(&baseInfo)
if err != nil {
fmt.Println("获取文件基本失败")
return nil, err
}
return &baseInfo, nil
}
// 下载文件
func downloadFile(filename string, downloadDir string) {
defer globalWait.Done()
fileInfo, err := getFileInfo(filename)
if err != nil {
fmt.Printf("%s文件下载失败", filename)
return
}
switch fileInfo.Filetype {
case "normal":
// 普通文件,直接整个下载
err := downloader.DownloadFile(filename, downloadDir)
if err != nil {
fmt.Printf("%s文件下载失败", filename)
}
case "slice":
// 切片文件
// 这里需要判断是否是下载到一半的文件,如果是则重新加载下载器,如果不是则重新创建下载器进行下载
dLoader := downloader.GetDownLoader(filename, downloadDir)
if dLoader == nil {
fmt.Printf("%s这是一个全新要下载的文件\n", filename)
dLoader = downloader.NewDownLoader(filename, downloadDir)
}
if dLoader == nil {
fmt.Printf("%s文件下载失败", filename)
}
dLoader.DownloadFileBySlice()
// 合并分片
dLoader.MergeDownloadFiles()
default:
fmt.Printf("%s未知的文件类型,下载失败\n", filename)
}
}
// 下载多个文件
func downloadFiles(filePaths string, downloadDir string) {
if !common.IsDir(downloadDir) {
fmt.Println("路径不存在", downloadDir)
os.Exit(-1)
}
files := strings.Split(filePaths, " ")
for _, file := range files {
globalWait.Add(1)
go downloadFile(file, downloadDir)
}
globalWait.Wait()
}
// listFiles 列出文件列表
func listFiles() {
targetUrl := common.BaseUrl + "listFiles"
req, _ := http.NewRequest("GET", targetUrl, nil)
resp, err := (&http.Client{}).Do(req)
if err != nil {
fmt.Println("获取文件列表信息失败", err.Error())
return
}
defer resp.Body.Close()
var fileinfos common.ListFileInfos
err = json.NewDecoder(resp.Body).Decode(&fileinfos)
if err != nil {
fmt.Println("获取文件列表信息失败")
return
}
fmt.Printf("%s %s\n", "文件名", "文件大小")
for _, fileinfo := range fileinfos.Files {
fmt.Printf("%s %d\n", fileinfo.Filename, fileinfo.Filesize)
}
}
func main() {
startTime := time.Now()
defer func() {
fmt.Println("程序运行时间:", time.Since(startTime))
}()
// 解析传入的参数
flag.Parse()
// 设置基础请求URL值
common.BaseUrl = fmt.Sprintf("http://%s:%d/", *serverIP, *serverPort)
switch *action {
case "upload":
// 上传文件
uploadFiles(*uploadFilepaths)
case "download":
// 下载文件
downloadFiles(*downloadFilenames, *downloadDir)
case "list":
// 列出文件
listFiles()
default:
fmt.Printf("unknow action: %s\n", *action)
os.Exit(-1)
}
}