78.上传文件及在服务器保存文件到任意路径

上传文件到服务器是一个常用的操作,而在服务器上保存文件就需要多多用心了。因为你不可能只在一个路径里保存文件,所以需要实践一下保存文件到任意位置。当然,前提是你的应用程序有这样的操作权限。
首先建立一个main.go文件,作为项目的起点。并使用一个网页模板JoelUploadFile.html,作为操作界面。


代码目录结构

在main文件中,准备好页面路径、上传路径、文件访问路径等,及相对应函数

/**
* CofoxS
* @Author:  Jian Junbo
* @Email:   junbojian@qq.com
* @Create:  2019/3/30 22:25
* Copyright (c) 2019 Jian Junbo All rights reserved.
*
* Description:  
*/
package main

import (
    "fmt"
    "goHttps/uilFileSys"
    "html/template"
    "log"
    "net/http"
)

func main() {
    fmt.Println("Hello Moon!")
    log.Println("随意指定文件保存路径!")

    //--页面路径
    http.HandleFunc("/", IndexHandler)

    //--上传文件
    http.HandleFunc("/fileSys/tmpUpload/", uilFileSys.FileTmpUpload)

    //----上传文件
    http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("tmp"))))

    websitename := ":90"
    http.ListenAndServe(websitename, nil)
}

func IndexHandler(writer http.ResponseWriter, request *http.Request) {
    //取消获取facicon.ico的访问
    if request.RequestURI == "/facicon.ico" {
        return
    }

    //---------绑定模板页 begin-------------
    t, err := template.ParseFiles("./templatefile/JoelUploadFile.html")
    if err != nil {
        fmt.Println("发生了错误!")
        fmt.Fprintln(writer, err)
    }

    t.ExecuteTemplate(writer, "JoelUploadFile.html", "")
    //---------绑定模板页 end---------------
}

需要绑定的模板文件 JoelUploadFile.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>企业上传文件</title>
    <style type="text/css">

        input{
            line-height: 20px;
            padding-left: 2px;
            padding-right: 2px;
            margin-left: 2px;
            margin-right: 2px;
            background-color: #eaf4fc;
            border-color: #b5c1e4;
            border-width: 1px;
            border-style: solid;
            border-radius: 3px;
        }

        /*上传文件*/
        .file {
            position: relative;
            display: inline-block;
            background: #D0EEFF;
            border: 1px solid #99D3F5;
            border-radius: 4px;
            padding: 4px 12px;
            overflow: hidden;
            color: #1E88C7;
            text-decoration: none;
            text-indent: 0;
            line-height: 20px;
        }

        .file input {
            position: absolute;
            font-size: 100px;
            right: 0;
            top: 0;
            opacity: 0;
        }

        .file:hover {
            background: #AADFFD;
            border-color: #78C3F3;
            color: #004974;
            text-decoration: none;
        }


    </style>
    <script type="text/javascript">
        /*同步数据*/
        function synkFile(srcObj, showObj, newObj) {
            var srcO = document.getElementById(srcObj);
            var showO = document.getElementById(showObj);
            var new0 = document.getElementById(newObj);
            /*if (srcO.value.length > 0) {
                showO.value = srcO.value;
            }
            */

            // showO.value = "";
            new0.innerText = "";
            for (var i = 0; i < srcO.files.length; i++) {
                // showO.value += srcO.files[i].name + "|";
                new0.innerText += srcO.files[i].name + "|\r\n";
            }
        }
        /*保存修改数据*/
        function saveF() {
            var frm = document.getElementById("formSave");
            var u_id = document.getElementById("u_Id");
            if (u_id.value.length <= 0) {
                alert('\'流水号\'丢失!');
                return;
            }
            frm.submit();
        }
    </script>
</head>
<body>
<div>企业上传文件,按照“平台》企业编号》系统》年月日”来储存文件,文件名使用生成时间</div>
<div>
    <form id="formSave"  enctype="multipart/form-data" action="/fileSys/tmpUpload/" method="post">
        <input id="u_Id" name="u_Id" type="text" value="joel"
               style="width: 500px; display: none;" readonly>
        <a href="javascript:;" class="file">上传附件<input type="file" id="uploadfile" name="uploadfile" multiple
                                                       style="cursor: pointer"
                                                       onchange="synkFile('uploadfile','u_ElectranicAttachment','new_ElectranicAttachment')"></a>
        <label id="show_ElectranicAttachment"></label>
        <label id="new_ElectranicAttachment"></label>
        <input id="u_ElectranicAttachment" name="u_ElectranicAttachment" type="text" value=""
               style="display: none">

        <div><input type="button" value="保存"  onclick="saveF()"></div>
    </form>
</div>
</body>
</html>

实现上传功能的函数

/**
* CofoxS
* @Author:  Jian Junbo
* @Email:   junbojian@qq.com
* @Create:  2019/3/31 23:27
* Copyright (c) 2019 Jian Junbo All rights reserved.
*
* Description:  企业文件管理
*/
package uilFileSys

import (
    "cofoxWebPlatform/platform/lib"
    "cofoxWebPlatform/platform/model"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "path"
)

//上传文件到临时文件路径,前提条件是当前用户是在线用户
func FileTmpUpload(writer http.ResponseWriter, request *http.Request)  {
    //接收数据
    keyId := request.FormValue("keyId")     //key身份Id

    //get a ref to the parsed  multipart form
    m := request.MultipartForm
    //get the *fileheaders
    files := m.File["uploadfile"]
    for i,_ := range files  {
        //save the file as filename
        filename := lib.JoelGetNowFullTimeNumber() +  path.Ext(files[i].Filename)

        //for each fileheader, get a handle to the actual file
        file, err := files[i].Open()
        defer file.Close()
        if err != nil {
            http.Error(writer, err.Error(), http.StatusInternalServerError)
            return
        }
        //create destination file making sure the path is writeable.
        dst, err := os.Create("./tmp/" + filename)
        defer dst.Close()
        if err != nil {
            http.Error(writer, err.Error(), http.StatusInternalServerError)
            return
        }
        //copy the uploaded file to the destination file
        if _, err := io.Copy(dst, file); err != nil {
            http.Error(writer, err.Error(), http.StatusInternalServerError)
            return
        }

        tmpfile := dst.Name()    // 写入保存文件的位置和文件名

        lib.JoelLog(keyId,tmpfile)  //服务端输出
        resultValue := model.JoelBaseAskResultNormal{}
        resultValue.AskResult = tmpfile
        back,_ := json.Marshal(resultValue)
        fmt.Fprint(writer,string(back)) //返回客端数据
    }
}

运行此程序


服务器显示

浏览器显示

点击“上传附件”,选择要上传的文件。


选择一个图片文件

点击“保存”按钮,激发js的saveF()函数,提交form到服务器
一般都会顺带提交一些其他数据,例如:u_Id

提交后,文件保存到 "/tmp/" 路径,这个路径在当前程序的根上。
已上传到服务器的文件

服务器返回的json串
下面可以指定保存的其他路径

当前文件保存的位置是 tmp 路径,是在 \uilFileSys\EntFileMS.go 中定义的

        //create destination file making sure the path is writeable.
        dst, err := os.Create("./tmp/" + filename)

用windows系统来举例,如果我希望文件保存在另一个位置,比如:e盘,这行代码只需要修改为

        //create destination file making sure the path is writeable.
        dst, err := os.Create("e://" + filename)

如果,你上传之后,还想能够通过浏览器访问到这个文件,那么在 main.go 中,有这样的一行代码

    //----上传文件
    http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("tmp"))))

你需要把它改成

    //----上传文件
    http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("e:\\"))))

至此,大功告成!你已经可以把文件上传到 e 盘了。
在此基础上,你应该可以动态的指定每次上传文件的物理路径了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容