用go语言写一个网盘支持多进程上传
时间: 2023-07-07 19:05:28 浏览: 97
以下是一个使用Go语言实现的支持多进程上传的简单网盘示例代码:
```go
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"strconv"
"strings"
"sync"
)
const (
maxUploadSize = 10 * 1024 * 1024 // 10 MB
uploadPath = "./uploads"
)
func main() {
http.HandleFunc("/upload", uploadFileHandler)
fmt.Println("Server started on :8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println(err)
return
}
}
func uploadFileHandler(w http.ResponseWriter, r *http.Request) {
// Check request method
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Method not allowed"))
return
}
// Check file size
r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
if err := r.ParseMultipartForm(maxUploadSize); err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("File too large"))
return
}
// Process multiple files concurrently
var wg sync.WaitGroup
for _, fileHeaders := range r.MultipartForm.File {
for _, fileHeader := range fileHeaders {
file, err := fileHeader.Open()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Failed to open file"))
return
}
defer file.Close()
// Create upload directory if not exists
os.MkdirAll(uploadPath, os.ModePerm)
// Generate unique file name
fileName := strings.Split(fileHeader.Filename, ".")[0]
fileExt := strings.Split(fileHeader.Filename, ".")[1]
filePath := fmt.Sprintf("%s/%s_%d.%s", uploadPath, fileName, time.Now().UnixNano(), fileExt)
// Upload file to disk
wg.Add(1)
go func() {
defer wg.Done()
saveFile(file, filePath)
}()
}
}
wg.Wait()
w.WriteHeader(http.StatusOK)
w.Write([]byte("Upload successful"))
}
func saveFile(file multipart.File, path string) error {
data, err := ioutil.ReadAll(file)
if err != nil {
return err
}
err = ioutil.WriteFile(path, data, os.ModePerm)
if err != nil {
return err
}
return nil
}
```
该示例代码中,我们使用了`net/http`模块创建了一个HTTP服务器,并实现了一个`/upload`接口用于处理上传文件的请求。当收到POST请求时,我们首先检查请求方法是否正确,并使用`http.MaxBytesReader`检查上传文件的大小是否超出了我们设定的最大值(10MB)。随后,我们利用`MultipartForm`解析请求体中的文件,并使用`sync.WaitGroup`实现了多进程上传,确保上传过程不会阻塞主线程。
在上传每个文件时,我们首先打开文件,随后创建一个上传目录(如果不存在),并生成一个唯一的文件名,最后使用`ioutil.WriteFile`将文件保存到本地磁盘中。
注意,由于多进程上传可能会导致文件名重复,因此我们需要在文件名中添加时间戳以确保唯一性。此外,我们还需要在保存文件时使用`defer`关闭文件句柄,以避免资源泄漏。
需要注意的是,本示例代码仅用于演示目的,实际应用中可能需要添加更多的安全和错误处理机制,例如身份验证、文件类型检查、异常处理等。
阅读全文