└── fileBlockUpload ├── backend ├── go.mod ├── go.sum └── main.go └── fontend └── index.html /fileBlockUpload/backend/go.mod: -------------------------------------------------------------------------------- 1 | module upload 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/gin-gonic/gin v1.6.3 7 | github.com/golang/protobuf v1.4.1 // indirect 8 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 9 | github.com/modern-go/reflect2 v1.0.1 // indirect 10 | golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c // indirect 11 | gopkg.in/yaml.v2 v2.3.0 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /fileBlockUpload/backend/go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 4 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 5 | github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= 6 | github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= 7 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 8 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 9 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 10 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 11 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 12 | github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= 13 | github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= 14 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 15 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 16 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 17 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 18 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 19 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 20 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 21 | github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= 22 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 23 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 24 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 25 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 26 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 27 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 28 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 29 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 30 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 31 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 32 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 33 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 34 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 35 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 36 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 37 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 38 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 39 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 40 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 41 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 42 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 43 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 44 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 45 | github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= 46 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 47 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 48 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 49 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= 50 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 51 | golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c h1:kISX68E8gSkNYAFRFiDU8rl5RIn1sJYKYb/r2vMLDrU= 52 | golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 53 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 54 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 55 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 56 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 57 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 58 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 59 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 60 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 61 | google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY= 62 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 63 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 64 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 65 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 66 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 67 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 68 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 69 | -------------------------------------------------------------------------------- /fileBlockUpload/backend/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/gin-gonic/gin" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | router := gin.Default() 13 | 14 | router.Use(Cors) 15 | router.GET("/checkChunk", func(c *gin.Context) { 16 | hash := c.Query("hash") 17 | hashPath := fmt.Sprintf("./uploadFile/%s", hash) 18 | chunkList := []string{} 19 | isExistPath, err := PathExists(hashPath) 20 | if err != nil { 21 | fmt.Println("获取hash路径错误", err) 22 | } 23 | 24 | if isExistPath { 25 | files, err := ioutil.ReadDir(hashPath) 26 | state := 0 27 | if err != nil { 28 | fmt.Println("文件读取错误", err) 29 | } 30 | for _, f := range files { 31 | fileName := f.Name() 32 | chunkList = append(chunkList, fileName) 33 | fileBaseName := strings.Split(fileName, ".")[0] 34 | if fileBaseName == hash { 35 | state = 1 36 | } 37 | } 38 | 39 | c.JSON(200, gin.H{ 40 | "state": state, 41 | "chunkList": chunkList, 42 | }) 43 | } else { 44 | c.JSON(200, gin.H{ 45 | "state": 0, 46 | "chunkList": chunkList, 47 | }) 48 | } 49 | }) 50 | 51 | router.POST("/uploadChunk", func(c *gin.Context) { 52 | fileHash := c.PostForm("hash") 53 | file, err := c.FormFile("file") 54 | hashPath := fmt.Sprintf("./uploadFile/%s", fileHash) 55 | if err != nil { 56 | fmt.Println("获取上传文件失败", err) 57 | } 58 | 59 | isExistPath, err := PathExists(hashPath) 60 | if err != nil { 61 | fmt.Println("获取hash路径错误", err) 62 | } 63 | 64 | if !isExistPath { 65 | os.Mkdir(hashPath, os.ModePerm) 66 | } 67 | 68 | err = c.SaveUploadedFile(file, fmt.Sprintf("./uploadFile/%s/%s", fileHash, file.Filename)) 69 | if err != nil { 70 | c.String(400, "0") 71 | fmt.Println(err) 72 | } else { 73 | chunkList := []string{} 74 | files, err := ioutil.ReadDir(hashPath) 75 | if err != nil { 76 | fmt.Println("文件读取错误", err) 77 | } 78 | for _, f := range files { 79 | fileName := f.Name() 80 | 81 | if f.Name() == ".DS_Store" { 82 | continue 83 | } 84 | chunkList = append(chunkList, fileName) 85 | } 86 | 87 | c.JSON(200, gin.H{ 88 | "chunkList": chunkList, 89 | }) 90 | } 91 | }) 92 | 93 | 94 | router.GET("megerChunk", func(c *gin.Context) { 95 | hash := c.Query("hash") 96 | fileName := c.Query("fileName") 97 | hashPath := fmt.Sprintf("./uploadFile/%s", hash) 98 | 99 | isExistPath, err := PathExists(hashPath) 100 | if err != nil { 101 | fmt.Println("获取hash路径错误", err) 102 | } 103 | 104 | if !isExistPath { 105 | c.JSON(400, gin.H{ 106 | "message": "文件夹不存在", 107 | }) 108 | return 109 | } 110 | isExistFile, err := PathExists(hashPath + "/" + fileName) 111 | if err != nil { 112 | fmt.Println("获取hash路径文件错误", err) 113 | } 114 | fmt.Println("文件是否存在", isExistFile) 115 | if isExistFile { 116 | c.JSON(200, gin.H{ 117 | "fileUrl": fmt.Sprintf("http://127.0.0.1:9999/uploadFile/%s/%s", hash, fileName), 118 | }) 119 | return 120 | } 121 | 122 | files, err := ioutil.ReadDir(hashPath) 123 | if err != nil { 124 | fmt.Println("合并文件读取失败", err) 125 | } 126 | complateFile, err := os.Create(hashPath + "/" + fileName) 127 | defer complateFile.Close() 128 | for _, f := range files { 129 | //.DS_Store 130 | //file, err := os.Open(hashPath + "/" + f.Name()) 131 | //if err != nil { 132 | // fmt.Println("文件打开错误", err) 133 | //} 134 | 135 | if f.Name() == ".DS_Store" { 136 | continue 137 | } 138 | 139 | fileBuffer, err := ioutil.ReadFile(hashPath + "/" + f.Name()) 140 | if err != nil { 141 | fmt.Println("文件打开错误", err) 142 | } 143 | complateFile.Write(fileBuffer) 144 | } 145 | 146 | c.JSON(200, gin.H{ 147 | "fileUrl": fmt.Sprintf("http://127.0.0.1:9999/uploadFile/%s/%s", hash, fileName), 148 | }) 149 | 150 | }) 151 | 152 | router.Run("127.0.0.1:9999") 153 | } 154 | 155 | func PathExists(path string) (bool, error) { 156 | _, err := os.Stat(path) 157 | if err == nil { 158 | return true, nil 159 | } 160 | if os.IsNotExist(err) { 161 | return false, nil 162 | } 163 | return false, err 164 | } 165 | 166 | func Cors(c *gin.Context) { 167 | c.Writer.Header().Set("Access-Control-Allow-Origin", "*") 168 | c.Writer.Header().Add("Access-Control-Allow-Headers", "Content-Type") 169 | 170 | c.Next() 171 | } -------------------------------------------------------------------------------- /fileBlockUpload/fontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 114 | 115 | --------------------------------------------------------------------------------