• golang点击下载文件与二维码下载文件


    背景

    有一个需求,可以通过点击按钮下载apk到pc端,也可以出现一个二维码,手机端扫描二维码下载文件,通过go语言实现

    实现

    点击下载

    我用的是gin框架,只需要输出到上下文即可下载。用过php的都知道,下载有个最简单的办法,将内容echo出来即可。
    1 查询apk文件的Content-Type,content-type对照表,找到apk对应application/vnd.android.package-archive
    2 编写下载代码,测试,发现必须有Content-Length属性,否则手机端会显示文件大小未知
    代码如下:

    // HandleDownloadFIle 下载文件
    func HandleDownloadFIle (c *gin.Context, fname string) {
        c.Writer.WriteHeader(http.StatusOK)
    	c.Header("Content-Disposition", "attachment; filename="+fname)
    	c.Header("Content-Type", "application/vnd.android.package-archive")
    	readF, _ := file.Open(fname, syscall.O_RDONLY, 0666)
    	var content []byte
    	buf := make([]byte, 1024)
    	for {
    		myLen, _ := readFile.Read(buf)
    		if myLen== 0 {
    			break
    		}
    		content = append(content, buf...)
    	}
    	sum := len(content)
    	c.Header("Content-Length", strconv.Itoa(sum))  // 这里我试过readFile.State().Size(),不准确,无法下载
    	c.Writer.Write(content)
    	readF.Close()
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    二维码下载

    其实可以直接链接到上一个下载地址即可,生成二维码就行了,我引入了"github.com/skip2/go-qrcode"这个包,LocalIPv4s这个方法是用来获取本地的ip列表,很简单,略,一般最后一个是内网ip。
    代码:

    // QrcodeDown 下载二维码
    func QrcodeDown(c *gin.Context) error {
    	urls, err := LocalIPv4s()
    	if len(urls) < 1 {
    		return errors.New("无法获取下载地址")
    	}
    	if err != nil {
    		return err
    	}
    	url := "http://" + urls[len(urls)-1] + "/old_download" // 这里拼接的是旧的下载地址
    	qrcode.WriteFile(url, qrcode.High, 256, "my_qrcode.png")
    	readF, _ := file.Open("my_qrcode.png", syscall.O_RDONLY, 0666)
    	c.Writer.WriteHeader(http.StatusOK)
    	c.Header("Content-Disposition", "attachment; filename=my_qrcode.png")
    	c.Header("Content-Type", "image/png")
    	var content []byte
    	buf := make([]byte, 1024)
    	for {
    		tmpLen, _ := readF.Read(buf)
    		if tmpLen == 0 {
    			break
    		}
    		content = append(content, buf...)
    	}
    	c.Writer.Write(content)
    	readF.Close()
    	return nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    12讲拆解量化金融时序分析,Kaggle master倾力奉献(中文翻译版)
    YOLOv5-seg数据集制作、模型训练以及TensorRT部署
    力扣114. 二叉树展开为链表
    完美收官 | IOTE第十八届国际物联网展精彩落幕,美格智能参展回顾
    源码中的设计模式--工厂模式
    idea如何创建并运行第一个java程序
    关于JAVA进阶你需要学习什么?
    使用动态sql对对象进行操作
    使用 Redis 实现分布式锁案例
    数据中心走向绿色低碳,液冷存储舍我其谁
  • 原文地址:https://blog.csdn.net/qq_28391061/article/details/136683419