golang实现FreeBSD部署minio分布式数据的上传、显示、下载

bsdx866 · 2023-09-04 08:22:34 · 1197 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2023-09-04 08:22:34 的主题,其中的信息可能已经有所发展或是发生改变。

golang实现FreeBSD部署minio分布式数据的上传、显示、下载

package main

import (
    "go-project/minio/weblib"
    "net/http"
)

func main() {
    // 通过多路复用器实现一个上传服务
    mux := http.NewServeMux()
    mux.HandleFunc("/uploadFile", weblib.UploadFile) //上传页模板
    mux.HandleFunc("/listFile", weblib.ListFile)     //文件列表模板
    mux.HandleFunc("/upload", weblib.Upload)         //处理上传文件的函数
    http.ListenAndServe(":80", mux)
}

实现一个weblib的库在main.go多路复用里面调用

package weblib

import (
    "go-project/minio/miniolib"
    "log"
    "net/http"
    "text/template"
)

func UploadFile(w http.ResponseWriter, r *http.Request) {
    tpl, err := template.ParseFiles("weblib/template/uploadfile.html")
    if err != nil {
        log.Println(err)
        return
    }
    tpl.Execute(w, nil)
}
func Upload(w http.ResponseWriter, r *http.Request) {
    err := r.ParseMultipartForm(1024)
    if err != nil {
        w.Write([]byte("没有上传文件,请重试"))
        return
    }
    for _, fileHead := range r.MultipartForm.File["upload"] {
        file, err := fileHead.Open()
        if err != nil {
            log.Println(err)
            return
        }
        defer file.Close()
        objContentType := fileHead.Header["Content-Type"]
        miniolib.UploadObj(fileHead.Filename, file, fileHead.Size, objContentType[0])
    }
}
func ListFile(w http.ResponseWriter, r *http.Request) {
    tpl, err := template.ParseFiles("weblib/template/list.html")
    if err != nil {
        log.Println(err)
        return
    }
    fileArray := miniolib.ListObj()
    tpl.Execute(w, fileArray)
}

实现一个miniolib库在weblib库里面调用

package miniolib

import (
    "context"
    "fmt"
    "io"
    "log"
    "net/url"
    "time"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
)

var client = clientConnect()
var ctx, _ = context.WithCancel(context.Background())
var bucketName = listBuckets(client)

// 初始化 minio 客户端连接对象
func clientConnect() *minio.Client {
    endpoint := "192.168.194.128:9000"
    accessKeyID := "ZK1Ed3khwlCb07wR"
    secretAccessKey := "bjxBx4O3n8HYeFyE2eJ2LG74jY1viCHx"
    useSSL := false

    client, err := minio.New(endpoint, &minio.Options{
        Creds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
        Secure: useSSL})
    if err != nil {
        log.Fatalln("minio连接错误: ", err)
    }
    return client
}

// 获取所有存储桶名称
func listBuckets(client *minio.Client) (BucketName string) {
    buckets, _ := client.ListBuckets(ctx)
    for _, bucket := range buckets {
        return bucket.Name
    }
    return
}

// 根据存储桶来存储对象
func UploadObj(objectName string, fp io.Reader, size int64, contentType string) {
    object, err := client.PutObject(context.Background(), bucketName, objectName, fp, size, minio.PutObjectOptions{ContentType: contentType})
    if err != nil {
        log.Println("上传失败:", err)
        return
    }
    fmt.Println(object)
    log.Printf("文件上传成功 %s of 文件大小为: %d\n", objectName, object.Size)
}

type ObjectType struct {
    FileName string
    FileType string
    FileUrl  string
}

// 列出桶里所有的存储对象,并存入ObjectType的这个结构体对象中,用于传入网页模板中
func ListObj() (fileInfo []ObjectType) {
    fileInfo = make([]ObjectType, 0)
    objectCh := client.ListObjects(context.Background(), bucketName, minio.ListObjectsOptions{
        WithVersions: true,
        WithMetadata: true,
        Recursive:    true,
    })
    for fileObjects := range objectCh {
        if fileObjects.Err != nil {
            log.Println(fileObjects.Err)
            return nil
        }
        fileUrl := getObjUrl(fileObjects.Key)
        fileInfo = append(fileInfo, ObjectType{
            FileName: fileObjects.Key,
            FileType: fileObjects.UserMetadata["content-type"],
            FileUrl:  fileUrl,
        })
        fmt.Printf("文件名:%s 文件类型:%s\n", fileObjects.Key, fileObjects.UserMetadata["content-type"])
    }
    return fileInfo
}

// 删除桶里面的对象
func RemoveObj(client *minio.Client, objName string) {
    err := client.RemoveObject(ctx, bucketName, objName, minio.RemoveObjectOptions{})
    if err != nil {
        log.Println(err)
        return
    }
}

// 获取minio通里对象的下载URL链接
func getObjUrl(filename string) (fileUrl string) {
    reqParams := make(url.Values)
    filenameValue := fmt.Sprintf("attachment; filename=\"%s\"", filename)
    reqParams.Set("response-content-disposition", filenameValue)

    presignedURL, err := client.PresignedGetObject(context.Background(), bucketName, filename, time.Second*24*60*60, reqParams)
    if err != nil {
        fmt.Println(err)
        return
    }
    return presignedURL.String()
}

一个简单的文件上传网页模板

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>上传、下载文件</title>
    <style type="text/css">
        #filedrag {
            display: none;
            font-weight: bold;
            text-align: center;
            padding: 1em 0;
            margin: 1em 0;
            color: #555;
            border: 2px dashed #555;
            border-radius: 7px;
            cursor: default;
        }
        #filedrag.hover {
            color: #f00;
            border-color: #f00;
            border-style: solid;
            box-shadow: inset 0 3px 4px #888;
        }
    </style>
</head>
<body>
<form id="upload" action="UploadServlet" enctype="multipart/form-data" method="post" onsubmit="return upLoad();">
    <p>
        <label for="fileselect">file name:</label><input multiple="true" type="file" id="fileselect" name="upload" />
    <div id="filedrag">或者将文件拖拽到这里</div>
    <div id="submitbutton">
        <input type="submit" value="提交">
    </div>
</form>
<div id="messages">
</div>

<script type="text/javascript">
    var upfiles = new Array();
    // getElementById
    function $id(id) {
        return document.getElementById(id);
    }
    // output information
    function Output(msg) {
        var m = $id("messages");
        m.innerHTML = msg + m.innerHTML;
    }
    // file drag hover
    function FileDragHover(e) {
        e.stopPropagation();
        e.preventDefault();
        e.target.className = (e.type == "dragover" ? "hover" : "");
    }
    // file selection
    function FileSelectHandler(e) {
// cancel event and hover styling
        FileDragHover(e);
// fetch FileList object
        var files = e.target.files || e.dataTransfer.files;
// process all File objects
        for ( var i = 0, f; f = files[i]; i++) {
            ParseFile(f);
            upfiles.push(f);
        }
    }
    // output file information
    function ParseFile(file) {
        Output("<p>文件信息: <strong>" + file.name
                + "</strong> 类型: <strong>" + file.type
                + "</strong> 大小: <strong>" + file.size
                + "</strong> bytes</p>");
    }
    function upLoad() {
        if (upfiles[0]) {
            var xhr = new XMLHttpRequest(); //Ajax异步传输数据
            xhr.open("POST", "/upload", true);
            var formData = new FormData();
            for ( var i = 0, f; f = upfiles[i]; i++) {
                formData.append('upload', f);
            }
            xhr.send(formData);
            xhr.onreadystatechange=function(e){
                history.go(0); //由于这个页面还要显示可以下载的文件,所以需要刷新下页面
            }
            return false;
        }
    }
    // initialize
    function Init() {
        var fileselect = $id("fileselect"), filedrag = $id("filedrag"), submitbutton = $id("submitbutton");
// file select
        fileselect.addEventListener("change", FileSelectHandler, false);
// is XHR2 available?
        var xhr = new XMLHttpRequest();
        if (xhr.upload) {
// file drop
            filedrag.addEventListener("dragover", FileDragHover, false);
            filedrag.addEventListener("dragleave", FileDragHover, false);
            filedrag.addEventListener("drop", FileSelectHandler, false);
            filedrag.style.display = "block";
// remove submit button
//submitbutton.style.display = "none";
        }
    }
    // call initialization file
    if (window.File && window.FileList && window.FileReader) {
        Init();
    }
</script>
</body>
</html>

一个简单的显示minio服务器里面文件的模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件列表</title>
</head>
<body>
    {{ range .}}
        <li>文件名:<a href="{{.FileUrl}}">{{.FileName}}</a> 文件类型:{{.FileType}}</li>

    {{end}}
</body>

</html>

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1197 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传