前言

曾经,因为不够注重基础吃了好多亏。总是很喜欢去看那些高大上的东西,却忽略了最基本的东西。然后会错误的以为自己懂的很多,但是其实是沙堆中筑高台,知道很多高大上的架构,但是基础的东西却不太了解。我觉得,可能这就是大部分开发工程师的通病吧。

所以,深入一门语言,也不用一直看重多高端、高大上的框架功能服务,尝试一下小案例,拓宽一下对于语言的更深层次的理解。

文章目录

  • 前言
  • 基础案例
    • 中文拼音转换
    • 解析二维码
    • 压缩文件成 zip
    • 执行定时任务
      • 自带原始库
      • 定时任务库选择
  • 总结

基础案例

  • 中文拼音转换:根据用户名快速创建个人 id
  • 解析二维码:帮助快速识别硬件码
  • 压缩 zip:压缩文件,便于传输数据
  • 执行定时任务:方便自动化操作

中文拼音转换

package mainimport ("fmt""github.com/mozillazg/go-pinyin"
)func main() {hans := "中国人"// 默认a := pinyin.NewArgs()fmt.Println(pinyin.Pinyin(hans, a))// [[zhong] [guo] [ren]]// 包含声调a.Style = pinyin.Tonefmt.Println(pinyin.Pinyin(hans, a))// [[zhōng] [guó] [rén]]// 声调用数字表示a.Style = pinyin.Tone2fmt.Println(pinyin.Pinyin(hans, a))// [[zho1ng] [guo2] [re2n]]// 开启多音字模式a = pinyin.NewArgs()a.Heteronym = truefmt.Println(pinyin.Pinyin(hans, a))// [[zhong zhong] [guo] [ren]]a.Style = pinyin.Tone2fmt.Println(pinyin.Pinyin(hans, a))// [[zho1ng zho4ng] [guo2] [re2n]]fmt.Println(pinyin.LazyPinyin(hans, pinyin.NewArgs()))// [zhong guo ren]fmt.Println(pinyin.Convert(hans, nil))// [[zhong] [guo] [ren]]fmt.Println(pinyin.LazyConvert(hans, nil))// [zhong guo ren]
}

实际应用过程中,只要能够获取需要转换的中文词语字符串数组即可实现中文拼音转换的操作,不过,虽然使用的包 github.com/Chain-Zhang/pinyin 相对于其他 golang 拼音转换项目的资料多一点,但貌似不维护了。

package mainimport ("fmt""github.com/mozillazg/go-pinyin""strings""reflect""github.com/astaxie/beego"
)func main() {hans := "中国人"a := pinyin.LazyConvert(hans, nil)// [zhong guo ren]var test []string = []string{}for a, v := range a{beego.Info(v)beego.Info(a)if a == 0 {test = append(test, v)} else {test = append(test, ",")test = append(test, v)}}beego.Info("处理1")beego.Info(test)//  通过这一条处理 strings.Trimresult := strings.Trim(fmt.Sprint(test), "[]")// result := strings.Replace(strings.Trim(fmt.Sprint(test), "[]"), " ", ",", -1)beego.Info(result)beego.Info(reflect.TypeOf(result))result2 := strings.Replace(result, " , ", "", -1)beego.Info(result2)// zhongguoren
}

运行代码如下:

go get -u github.com/mozillazg/go-pinyin
go run main.go

可得以下结果:

解析二维码

思路:

  1. 上传图片或者本地读取图片
  2. 将文件流写入到gozxing 的函数中解析二维码
    这里采用上传文件的形式,如下:
package mainimport ("fmt""image"_ "image/gif"_ "image/jpeg"_ "image/png""github.com/makiuchi-d/gozxing""github.com/makiuchi-d/gozxing/qrcode""github.com/gin-gonic/gin""net/http""io"
)func main() {router := gin.Default()router.POST("/upload", func(c *gin.Context) {// The default memory allocation is 10Mfile, err := c.FormFile("filename")if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))return}//文件大小限制if file.Size > (10 << 20) {c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", "文件太大,请重新上传"))return}c.String(http.StatusOK, fmt.Sprintf("File %s uploaded success", file.Filename))//fmt.Println(file.Filename, "文件名")fi, err := file.Open()if err != nil {fmt.Println(err)}defer fi.Close()str := GetPaymentStr(fi).String()fmt.Println("qrcode_url:", str)})router.Run(":8000")
}func GetPaymentStr(fi io.Reader) (paymentCodeUrl *gozxing.Result) {img, _, err := image.Decode(fi)if err != nil {fmt.Println(err)}// prepare BinaryBitmapbmp, _ := gozxing.NewBinaryBitmapFromImage(img)// decode imageqrReader := qrcode.NewQRCodeReader()result, err := qrReader.Decode(bmp, nil)if err != nil {fmt.Println(err)}return result
}

注意使用的图片格式包,需要哪种格式,才导入哪种格式,剔除冗余文件。


注意关闭文件流哦!


图片拷贝不如,基本就要再读写一次,不如同时开两个流

压缩文件成 zip

在软件很多应用开发过程中,经常需要使用到文件压缩。有时候是为了加快存盘速度,有时候是为了节省硬盘空间,有时候是为了提高传输效率。gzip是一种比较通用的压缩程序,golang系统自带的包里边compress/gzip就可以实现在代码中实现gzip的功能。

定义解压缩文件接口CompressFile和DeCompressFile:
gziptest.go:

package gziptestimport ("compress/gzip""io""os"
)//压缩文件Src到Dst
func CompressFile(Dst string, Src string) error {newfile, err := os.Create(Dst)if err != nil {return err}defer newfile.Close()file, err := os.Open(Src)if err != nil {return err}zw := gzip.NewWriter(newfile)filestat, err := file.Stat()if err != nil {return nil}zw.Name = filestat.Name()zw.ModTime = filestat.ModTime()_, err = io.Copy(zw, file)if err != nil {return nil}zw.Flush()if err := zw.Close(); err != nil {return nil}return nil
}//解压文件Src到Dst
func DeCompressFile(Dst string, Src string) error {file, err := os.Open(Src)if err != nil {panic(err)}defer file.Close()newfile, err := os.Create(Dst)if err != nil {panic(err)}defer newfile.Close()zr, err := gzip.NewReader(file)if err != nil {panic(err)}filestat, err := file.Stat()if err != nil {panic(err)}zr.Name = filestat.Name()zr.ModTime = filestat.ModTime()_, err = io.Copy(newfile, zr)if err != nil {panic(err)}if err := zr.Close(); err != nil {panic(err)}return nil
}

单元测试用例(调用函数):
gziptest_test.go:


package gziptestimport ("os""testing"
)func TestCompressFile(t *testing.T) {pwd, _ := os.Getwd()newfile, err := os.Create(pwd + "/test.txt")if err != nil {t.Fatal(err)}newfile.Write([]byte("hello world!!!!"))newfile.Close()err = CompressFile(pwd+"/test.gz", pwd+"/test.txt")if err != nil {t.Fatal(err)}
}func TestDeCompressFile(t *testing.T) {pwd, _ := os.Getwd()err := DeCompressFile(pwd+"/test2.txt", pwd+"/test.gz")if err != nil {t.Fatal(err)}
}

测试结果:

C:/Go/bin/go.exe test -v [D:/go/src/gziptest]
=== RUN   TestCompressFile
--- PASS: TestCompressFile (0.00s)
=== RUN   TestDeCompressFile
--- PASS: TestDeCompressFile (0.00s)
PASS
ok      gziptest    2.351s

同级目录下增加了三个文件:

  • test.txt
  • text2.txt
  • text.gz
    其中test.txt和test2.txt内容为:
hello world!!!!
1

test.gz内容为text.txt

执行定时任务

golang中需要定时执行某些任务,完成一些自动化操作。

自带原始库


func DocSyncTaskCronJob() {ticker := time.NewTicker(time.Minute * 1) // 每分钟执行一次for range ticker.C {ProcTask()}
}func ProcTask() {log.Println("hello world")
}

调研一下后发现Golang并没有十分完善的定时任务库。无法完成复杂的定时任务。

  • 事件订阅/通知机制不成熟
  • 无法适用于更灵活的场景,例如多节点的分布式任务调度执行
  • 模块之间的职责不清晰,例如其实Timer模块是Scheduler调度器的一部分,Event定时器相关的部分也是Scheduler调度器的一部分,而Executor执行模块也存在任务调度的功能,实际上它只需要负责完成调度器交给它的任务就好
  • 没有设计任务调度池,也就是但凡新建计划任务,就会在后台启动一个协程持续监听;一旦任务数量太多,后台停留的协程会越来越多,进程总的消耗就会变得非常夸张,非常可怕
  • 任务调度时不存在优先级的概念,假如相同时间内有多个任务同时执行,哪个任务被优先调度完全取决于GMP的系统调度

定时任务库选择

目前比较主流两种go常用定时库

  • robfig/cron:说到定时任务,会想到 crontab,其常见于Unix和类Unix的操作系统之中。robfig/cron 库使用了类 crontab 的方式来执行定时任务。
  • jasonlvhit/gocron:类 crontab 的设置方式可能并不友好,jasonlvhit/gocron 提供了更为人性化的执行方式。

这里我们使用开源库:robfig/cron
安装库:

go get -u github.com/jasonlvhit/gocron
package main
import("fmt"cron "github.com/robfig/cron/v3"
)func main() {crontab := cron.New()task := func() {fmt.Println("hello world")}// 添加定时任务, * * * * * 是 crontab,表示每分钟执行一次crontab.AddFunc("* * * * *", task)// 启动定时器crontab.Start()// 定时任务是另起协程执行的,这里使用 select 简答阻塞.实际开发中需要// 根据实际情况进行控制select {}
}

执行命令:

go get github.com/robfig/cron/v3@v3.0.0
go run  main.go

执行效果如下:

当然,更为复杂的定时任务还有待大家去设计,这里只是一个个小小的案例。

总结

总的来说,一个个小小案例,能够帮助我们了解到许多的工具库与框架,并且理解一些小功能的实现思路,尔后,慢慢利用这些小功能积累成一个个高效、强大的服务模块,这也是徐徐渐进的过程,一起加油!

Golang 基础案例集合:中文拼音转换、解析二维码、压缩 zip、执行定时任务相关推荐

  1. java利用zxing来生成和解析二维码,支持中文

    java在二维码的生成和解析上,网上有些人说如果要解析中文,得去修改工具包的Encoder类中的 static final String DEFAULT_BYTE_MODE_ENCODING = &q ...

  2. Python解析二维码、条形码

    Python解析二维码.条形码 1 前言 2 二维码知识小科普 2.1 什么是二维码 2.2 二维码的结构 2.3 二维码的绘制过程 3 Python解析二维码 3.1 准备工作: 3.2 pyzba ...

  3. Java生成和解析二维码

    前言:曾经有做过不少微信公众号和移动网站的项目,对二维码还算有点了解,刚收到这个任务的时候就想着竟然要用二维码存文本,那就得先考究一下这小小的二维码到底能存多少的东西了. 需求:使用二维码存放文本(x ...

  4. Java生成解析二维码

    Java生成二维码 一.介绍 1. 理解二维码 黑点代表二进制中的1,白点代表二进制中的0,通过1和0的排列组合,在二维空间记录数据.通过图像输入设备,读取其中的内容. 2. 二维码分类 二维码有不同 ...

  5. java生成二维码/java解析二维码

    二维码的优缺点 优点:1. 高密度编码,信息容量大:2.编码范围广:3.容错能力强:4.译码可靠性高:5.可引入加密措施:6.成本低,易制作,持久耐用. 缺点:1.二维码技术成为手机病毒.钓鱼网站传播 ...

  6. opencv图像处理中的一些滤波器+利用滤波器提取条形码(解析二维码)+公交卡倾斜矫正+物体尺寸丈量

    一般来说,图像的能量主要集中在其低频部分,噪声所在的频段主要在高频段,同时图像中的细节信息也主要集中在其高频部分,因此,如何去掉高频干扰同时又保持细节信息是关键.为了去除噪声,有必要对图像进行平滑,可 ...

  7. 使用摄像头解析二维码,且可以生成含具体信息的二维码

    开源一份早些时候写过的代码,关于二维码在PC端的应用. 二维码的具体应用范围,这里不详述. 之前项目主要用于朋友一个牙科的平台,不过后面没有采用,也就没有往后继续开发,大家要是觉得有意思,可以自己拿去 ...

  8. C# 调用摄像头解析二维码

    上次的二维码项目中,在解析的时候用的是扫码枪自动解析并以键盘形式输出,二次开发及通用性不高.本次项目使用AForge库调用摄像头采集二维码照片,再使用ZXing库解析二维码,较之前通用性更高. 一.调 ...

  9. 利用ZXing工具生成二维码以及解析二维码

    今天突然想到二维码是如何存储信息的.于是就开始各种搜索,最终自己也利用Google的ZXing工具完成了一个生成二维码和解析二维码的简单程序. 一. 二维码生成原理(即工作原理) 二维码官方叫版本Ve ...

最新文章

  1. AI研究生应届生年薪可达50万 没出校门已被抢光
  2. NHibernate初学者指南(1):开篇
  3. 网络推广——网络推广专员从多角度分析网站关键词排名受影响因素
  4. 无法找到脚本文件adsutil.vbs的解决方法
  5. php 利用scandir() 函数 扫描出制定目录下的所有文件
  6. IOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem
  7. ps -ef 输出结果的具体含义
  8. python处理shp和栅格文件的相关库shapefile、gdal等
  9. ViewPage最全解析
  10. 信息系统审计(IT审计)实践
  11. 【论文写作】毕业论文怎么写?写作步骤是什么?
  12. pandas 学习(四)—— 数据处理(清洗)、缺失值的处理
  13. webpack全局安装和安装过程中碰见的一些坑(npm error)解决方案
  14. 重装windows10系统的教程
  15. HDU 4699 Editor(双向链表)
  16. 已知鸡兔的脚一共80只C语言,鸡兔同笼鸡比兔多10只但鸡脚却比兔脚少60只问鸡兔各几只...
  17. [Unity3D]Unity3D游戏开发之自由视角下的角色控制
  18. 数据挖掘-决策树算法的R实现
  19. 编译go文件时内部包引用受限的问题(use of internal package /PATH/ not allowed)
  20. jdk1.9的安装与环境配置

热门文章

  1. unity音频 Android,unity发布到Android的音频解决方案
  2. 产品经理从专能到全能——较真的App界面交互设计规范
  3. 关于iPhone6/6Plus分辨率及图片分辨率的问题(一)
  4. 离开IBM多年,我依然怀念它
  5. postgis中构造geojson
  6. C#操作mysql数据库的封装类(封装函数方法)
  7. 明日之后什么服务器物品最便宜,明日之后:交易之城如何买到便宜东西,一件装备省几万很轻松...
  8. 8. Fabric2.2 区块链农产品溯源系统 - 智能合约设计
  9. 在网页中插入视频播放代码
  10. easyexcel功能扩展:读取excel日期格式(包括日期格式和文本格式)