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

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 := "xxxxxxxxxxxxxxxx"
	secretAccessKey := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	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>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值