go从指定的 URL 下载图片并保存到本地

这段代码定义了一个名为 downloadImage 的函数,其目的是从指定的URL下载图片并保存到本地文件系统。以下是对代码功能的详细描述:


1.函数定义

该函数接受一个 imageName 参数,图片的文件名。

2.构建图片URL

使用 fmt.Sprintf 函数构建图片的URL,这个URL指向一个特定的网络路径,用于下载图片。

url := fmt.Sprintf("https://xxxxxxx.com.cn/pic/l/sevp_nsmc_wxbl_fy4b_etcc_achn_lno_py_%s", imageName)

3.检查图片是否存在:

发起一个HEAD请求到构建的URL,检查图片是否存在。
如果图片不存在(HTTP 404),记录一条日志并返回,不进行下载操作。

resp, err := http.Head(url)
if err != nil {
	log.Println(err)
	return // 发生错误时,跳过当前循环
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusNotFound {
	log.Printf("图片 %s 不存在于服务器\n", imageName)
	return // 图片不存在时,跳过当前循环
}

4.下载图片

如果图片存在,发起一个GET请求,从URL下载图片。

response, err := http.Get(url)
if err != nil {
	log.Println(err)
	return
}

5.创建本地文件

根据图片名称和预设的路径创建一个本地文件夹,用于保存下载的图片。

filepath := fmt.Sprintf("./uploads/image/%s", imageName)
file, err := os.Create(filepath)
if err != nil {
	log.Println(err)
	return
}

6.保存图片到本地

下载的图片内容写入到本地文件中。

_, err = io.Copy(file, response.Body)
if err != nil {
	log.Println(err)
	return
}

7.完整代码

在整个过程中,对任何可能发生的错误进行捕获和记录。
使用 defer 语句确保在函数返回之前关闭打开的文件和网络连接,释放资源。

func downloadImage(imageName string) {
	url := fmt.Sprintf("https://xxxxxxx.com.cn/pic/l/sevp_nsmc_wxbl_fy4b_etcc_achn_lno_py_%s", imageName)
	// 如果不存在,检查 HTTP 状态码
	resp, err := http.Head(url)
	if err != nil {
		log.Println(err)
		return // 发生错误时,跳过当前循环
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusNotFound {
		log.Printf("图片 %s 不存在于服务器\n", imageName)
		return // 图片不存在时,跳过当前循环
	}
	response, err := http.Get(url)
	if err != nil {
		log.Println(err)
		return
	}
	defer response.Body.Close()

	filepath := fmt.Sprintf("./uploads/image/%s", imageName)
	file, err := os.Create(filepath)
	if err != nil {
		log.Println(err)
		return
	}
	defer file.Close()

	_, err = io.Copy(file, response.Body)
	if err != nil {
		log.Println(err)
		return
	}
}

总结

总结来说,这段代码的主要功能是尝试从指定的URL下载图片,并在下载前检查图片是否存在。如果存在,则下载并保存到本地;如果不存在,则记录错误并跳过下载。同时,它还处理了可能出现的错误,并确保在函数结束时正确地关闭了所有资源。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是服务端代码,使用Go语言编写,通过HTTP协议提供文件下载服务: ```go package main import ( "fmt" "io" "net/http" "os" ) func main() { http.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) { // 获取文件名 filename := r.URL.Query().Get("filename") if filename == "" { http.Error(w, "missing filename parameter", http.StatusBadRequest) return } // 打开文件 file, err := os.Open(filename) if err != nil { http.Error(w, fmt.Sprintf("failed to open file %s: %v", filename, err), http.StatusInternalServerError) return } defer file.Close() // 设置响应头 w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename)) w.Header().Set("Content-Type", "application/octet-stream") // 写入响应体 if _, err = io.Copy(w, file); err != nil { http.Error(w, fmt.Sprintf("failed to write file to response: %v", err), http.StatusInternalServerError) return } }) // 监听端口 if err := http.ListenAndServe(":8080", nil); err != nil { panic(err) } } ``` 客户端代码如下,通过HTTP协议从服务端获取文件并保存本地: ```go package main import ( "fmt" "io" "net/http" "os" ) func main() { // 获取命令行参数 if len(os.Args) != 4 { fmt.Println("usage: demo file [filename] [server address]") return } filename := os.Args[2] serverAddr := os.Args[3] // 发送请求 resp, err := http.Get(fmt.Sprintf("http://%s/download?filename=%s", serverAddr, filename)) if err != nil { fmt.Printf("failed to download file %s from server %s: %v\n", filename, serverAddr, err) return } defer resp.Body.Close() // 创建文件 file, err := os.Create(filename) if err != nil { fmt.Printf("failed to create file %s: %v\n", filename, err) return } defer file.Close() // 写入文件 if _, err = io.Copy(file, resp.Body); err != nil { fmt.Printf("failed to save file %s: %v\n", filename, err) return } fmt.Printf("file %s downloaded from server %s\n", filename, serverAddr) } ``` 使用命令 `go build` 分别编译服务端和客户端程序,然后在不同的终端窗口中启动服务端和客户端程序,即可进行文件下载。例如,启动服务端程序: ``` $ ./server ``` 启动客户端程序,并从服务端下载文件 `test.txt`: ``` $ ./client file test.txt 192.168.1.1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值