golang无法下载包的问题

下载第三方包失败

由于众所周知的不可抗力的原因,国内开发Go非常难受,一些包总是下载不成功。但是这难不倒广大的秃头猩猩。

方式一: 配置代理地址

配置代理,最方便,最直接,无需多余的操作 ,以下我知道的几个(第一和第二个我使用过,还行):

mac os 下,执行下面的命令即可

1
2
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

想了解更详细的知识,可访问他们的官方网站。

如果配置了代理,还不行,请检查变量 GOSUMDB, 一般默认值为: sum.golang.org, GOSUMDB(go checksum database)是Go官方为了go modules安全考虑, 设定的module校验数据库,服务器地址为:sum.golang.org.

你想的没错,还是那个原因,无法访问这个地址。 解决办法:

  1. 关闭 GOSUMDB, 设置为 off 即可,(不太安全,不推荐)
  2. 寻找中…

方式二: 科学上网代理

这个就不说了,只要能科学的访问网络,那么一切都不是问题了。

作者

Fat Dong

发布于

2022-03-24

更新于

2022-03-24

许可协议

golang-echo框架上传文件

golang-echo框架上传文件

Echo 是一个 golang 的 web框架,官方描述为:

1
2
Echo
High performance, extensible, minimalist Go web framework

最近在学习文件上传功能,直接复制官方demo是正常可以运行的,但是自己添加了一些逻辑就不行了,
官方的一个简易demo:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package main

import (
"fmt"
"io"
"net/http"
"os"

"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)

func upload(c echo.Context) error {
// Read form fields
name := c.FormValue("name")
email := c.FormValue("email")

//-----------
// Read file
//-----------

// Source
file, err := c.FormFile("file")
if err != nil {
return err
}
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()

// Destination
dst, err := os.Create(file.Filename)
if err != nil {
return err
}
defer dst.Close()

// Copy
if _, err = io.Copy(dst, src); err != nil {
return err
}

return c.HTML(http.StatusOK, fmt.Sprintf("<p>File %s uploaded successfully with fields name=%s and email=%s.</p>", file.Filename, name, email))
}

func main() {
e := echo.New()

e.Use(middleware.Logger())
e.Use(middleware.Recover())

e.Static("/", "public")
e.POST("/upload", upload)

e.Logger.Fatal(e.Start(":1323"))
}

我自己的demo:

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
file, err := c.FormFile("file")
if err != nil {
return err
}
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
md5, _ := util.FileMd5(src)
// Destination
dest := md5 + filepath.Ext(file.Filename)
dst, err := os.Create(file.Filename)
if err != nil {
return err
}
defer dst.Close()

// Copy
wr, err := io.Copy(dst, src)
if err != nil {
return err
}
fmt.Println(wr)
return c.HTML(http.StatusOK, fmt.Sprintf("<p>文件名字: %s,新名字:%s.</p>", file.Filename,dest))

md5 函数:

1
2
3
4
5
6
7
8
9
func FileMd5(file multipart.File) (string, error) {
h := md5.New()
_, err := io.Copy(h, file)
if err != nil {
return "", err
}
file.Seek(0, 0)
return hex.EncodeToString(h.Sum(nil)), nil
}

一步步地debug,发现最后 io.copy 之后,wr 写入数据量为0,而且只是增加了一个MD5地过程,发现有两次的 io.copy,猜测问题可能出在这里,

刚入门,后端一些知识不是很了解,只能寻求广大网友了,于是乎就找到办法了:

1
file.Seek()

知识点

io.copy 是一个很好用的方法, 它是将源复制到目标,并且是按默认的缓冲区32k循环操作的,不会将内容一次性全写入内存中,这样就能解决大文件的问题。(网上抄的)

file.Seek() 跳转到文本中的某处,并返回此处的偏移量,

原因

简单的来讲,文件整体读取完之后,读取位置就跑到的最后,然后再次,copy的时候,就会从上次的位置继续读取,那么肯定是读取不到的,所有要想继续读取,可以使用 file.Seek(0,0) 让文件指针移到开始位置,那么下次就会从开始位置读取了

作者

Fat Dong

发布于

2022-03-24

更新于

2022-03-24

许可协议

go run提示undefined

今天从GitHub上面 clone 的一个项目,本想本地运行学习一下,没想到 go run 的时候 ,提示变量 undefined. 之前一直在goland下开发, 使用的是ide的 go run,没出现这种问题

提示信息:

# command-line-arguments
./main.go:21:9: undefined: args
./main.go:26:14: undefined: args

解决办法之一

一般来说,main 包下推荐只有一个 main.go 的入口文件

当有其他的go文件 , 并且在其他go文件中定义了函数

如果非得这样做那么go run 的时候把所有文件都得加上 , 否则默认只加载main.go这一个文件

只有非main包里的文件才会通过依赖去自动加载。所以你需要输入多个文件作为参数

应该使用 go run a.go b.go c.gogo run *.go 来运行,编译同理。

作者

Fat Dong

发布于

2022-03-10

更新于

2022-03-12

许可协议