码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 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
  • 相关阅读:
    剑指Offer 36.二叉搜索树与双向链表 中序遍历
    集成学习 #数据挖掘 #Python
    【SG滤波】三阶滤波、五阶滤波、七阶滤波(Matlab代码实现)
    厌烦了iPhone默认的热点名称?如何更改iPhone上的热点名称
    Spring Cloud(十一):Spring Cloud Security Oauth2
    spark order by + limit 导致 java.lang.OutOfMemoryError: Java heap space
    service 自我升级遇到的问题
    【导航】嵌入式 Linux 学习专栏目录 【快速跳转】
    痞子衡嵌入式:不同J-Link版本对于i.MXRT1170连接复位后处理行为有所不同
    第3部分 静态路由
  • 原文地址:https://blog.csdn.net/qq_28391061/article/details/136683419
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号