Golang从文件服务器获取图片显示到客户端
一、需求
A(客户端)---------------》B(服务端)--------------》C(文件服务器)
在客户端需要显示图片列表,但是不想C(文件服务器)的地址被暴露出来,所以现在是A(客户端)发送URL到B(服务器),B(服务器)去请求C(文件服务器)的图片返回数据,B(服务器)返回图片到A(客户端)显示
注:B和C部署在不同的服务器
二、方法
1.如果C(文件服务器)是和B(服务端)部署在同一服务器,可以通过os.Open(filename string)(file *File,err error)直接将图片输出;
2.如果C(文件服务器)不是和B(服务端)部署在同一服务器,可以通过获取图片的数据经过base64后转化将数据输出到客户端;
3.如果C(文件服务器)不是和B(服务端)部署在同一服务器,通过B(服务端)获取C(文件服务器)的图片数据,直接将图片返回给客户端(下面实现)
三、实现方法3
1.如何将图片可以直接输出到客户端,可根据os.Open(filename string)(file *File,err error)方法来实现返回http.File接口类型即可;
2.查看golang标准库可知道http.File类型接口的实现(net/http)
type File interface {
io.Closer
io.Reader
Readdir(count int) ([]os.FileInfo, error)
Seek(offset int64, whence int) (int64, error)
Stat() (os.FileInfo, error)
}
3.通过看http.File接口的方法返回值还需要去实现os.FileInfo类型的接口(查看文档os)
type FileInfo interface {
Name() string // 文件的名字(不含扩展名)
Size() int64 // 普通文件返回值表示其大小;其他文件的返回值含义各系统不同
Mode() FileMode // 文件的模式位
ModTime() time.Time // 文件的修改时间
IsDir() bool // 等价于Mode().IsDir()
Sys() interface{} // 底层数据来源(可以返回nil)
}
4.只要实现了http.File和os.FileInfo两个接口就可以返回能够输出到客户端的类型,实现以下方法
func Close() (err error)
func Read(p []byte) (n int, err error)
func Readdir(count int) ([]os.FileInfo, error)
func Seek(offset int64, whence int) (int64, error)
func Stat() (os.FileInfo, error)
func Name() string
func Size() int64
func Mode() os.FileMode
func ModTime() time.Time
func IsDir() bool
func Sys() interface{}
四、代码实现
package main import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"time"
) //实现File和FileInfo接口的类
type ReadImg struct {
buf *bytes.Reader
fileUrl string
fileData []byte
} //获取C的图片数据
func ReadImgData(url string) []byte {
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
pix, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
return pix
} //实现File和FileInfo接口
func (r *ReadImg) Close() (err error) {
return nil
} func (r *ReadImg) Read(p []byte) (n int, err error) {
return r.buf.Read(p)
} func (r *ReadImg) Readdir(count int) ([]os.FileInfo, error) {
var i os.FileInfo = &ReadImg{buf: bytes.NewReader(r.fileData), fileUrl: r.fileUrl, fileData: r.fileData}
return []os.FileInfo{i}, nil
} func (r *ReadImg) Seek(offset int64, whence int) (int64, error) {
return r.buf.Seek(offset, whence)
} func (r *ReadImg) Stat() (os.FileInfo, error) {
var i os.FileInfo = &ReadImg{buf: bytes.NewReader(r.fileData), fileUrl: r.fileUrl, fileData: r.fileData}
return i, nil
} func (r *ReadImg) Name() string {
return filepath.Base(r.fileUrl)[:len(filepath.Base(r.fileUrl))-4]
} func (r *ReadImg) Size() int64 {
return (int64)(len(r.fileData))
} func (r *ReadImg) Mode() os.FileMode {
return os.ModeSetuid
} func (r *ReadImg) ModTime() time.Time {
return time.Now()
} func (r *ReadImg) IsDir() bool {
return false
} func (r *ReadImg) Sys() interface{} {
return nil
} //处理请求
type HttpDealImg struct{} func (self HttpDealImg) Open(name string) (http.File, error) {
img_name := name[1:]
fmt.Println(img_name)
img_url := "http://localhost:8001/images/Test" + name //C(文件服务器地址)
img_data := ReadImgData(img_url) //向服务器气球图片数据
if len(img_data) == 0 {
fmt.Println("file access forbidden:", name)
return nil, os.ErrNotExist
}
fmt.Println("get img file:", img_url)
var f http.File = &ReadImg{buf: bytes.NewReader(img_data), fileUrl: img_name, fileData: img_data} //标红的可以查看标准库bytes的Reader类型,NewReader(p []byte)可返回*Reader,然后调用和http.File相同的Seek()和Read()方法
return f, nil
} func InitHttpImgFileServ() {
http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(HttpDealImg{})))
} func main() {
InitHttpImgFileServ()
http.ListenAndServe(":8000", nil)
}
六、测试截图

请求地址http://localhost:8000/img/qq.png

后台打印的信息是获取的是http://localhost:8001/images/Test/qq.png,也就是C(文件服务器里图片的真实地址)
七、结束
当文件保存在其他的服务器上,需要在客户端显示图片,但是不想被知道真实的路径的时候就可以通过http.File和os.FileInfo去封装一下就可以实现,可能上面介绍的不清楚,有问题的可以留言一起沟通学习一下,谢谢!
如果有更好的实现方法,希望大家可以分享出来一起学习,谢谢、
Golang从文件服务器获取图片显示到客户端的更多相关文章
- Android相机、相册获取图片显示并保存到SD卡
Android相机.相册获取图片显示并保存到SD卡 [复制链接] 电梯直达 楼主 发表于 2013-3-13 19:51:43 | 只看该作者 |只看大图 本帖最后由 happy小妖同学 ...
- 从网络中获取图片显示到Image控件并保存到磁盘
一.从网络中获取图片信息: /// <summary> /// 获取图片 /// </summary> /// <param name="url"&g ...
- 根据url路径获取图片并显示到ListView中
项目开发中我们需要从网络获取图片显示到控件中,很多开源框架如Picasso可以实现图片下载和缓存功能.这里介绍的是一种简易的网络图片获取方式并把它显示到ListView中. 本案例实现的效果如下: 项 ...
- Android ListView从网络获取图片及文字显示
上一篇文章说的是ListView展示本地的图片以及文本,这一篇说一下如何从网络获取图片以及文本来显示.事实上,一般是先获取Josn或sml数据,然后解释显示.我们先从网上获取xml,然后对其进行解析, ...
- iOS 七牛云上传并获取图片----【客户端】
最近做了七牛云存储的有关内容,涉及到与后台交互获取验证的token,无奈,后台自命清高,不与理会,没办法呀,于是自己搞呗.首先呢在在七牛上注册一个账号,然后呢添加一个存储空间这时候空间名 ...
- ios 从网络上获取图片并在UIImageView中显示
ios 从网络上获取图片 -(UIImage *) getImageFromURL:(NSString *)fileURL { NSLog(@"执行图片下载函数"); UIIm ...
- Android从服务端获取json解析显示在客户端上面
Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Jso ...
- 获取Assets目录下的图片显示并上传
package com.jingle.getlocal; import java.io.ByteArrayOutputStream; import java.io.InputStream; impor ...
- ajax 获取 mysql 保存的图片显示
function ajax_GetFirstData(data) { var len = data.Data.length; if (len > 0) { $("#jquery_jpl ...
随机推荐
- redis HyperLogLog 基数估算
HyperLogLog 可以接受多个元素的输入,返回输入元素的基数估算值基数,集合中不同元素的数量.如集合{1,2,3,1,2,3,4}的基数是4.估算,HyperLogLog算法返回的基数不是完全精 ...
- SQL Server的优点与缺点
一般来说索引会加快查询速度,但会影响插入,修改,删除的数据,且占用物理空间;所以我们应该合理的创建索引,而且应该先创建聚合索引,再创建非聚合索引.要在经常进行查询的列上创建索引,而且如果表列较少的话要 ...
- JQuery 选择器 筛选器
什么是jQuery对象 参考:http://jquery.cuishifeng.cn/css.html jQuery 对象就是通过jQuery包装DOM对象后产生的对象.jQuery 对象是 jQue ...
- map合并,相同键对应的值相加
最近在做统计钱的计算时遇到的一个需求,需要将一个大类别下的每一种钱进行特定的运算然后获得六年的钱,最后将这些钱按照年份进行汇总,获得总得大类型的六年的钱,在这个过程中采用了这种方法,每次算得钱放在ma ...
- 【Redis】命令学习笔记——哈希(hash)(15个超全字典版)
本篇基于redis 4.0.11版本,学习哈希(hash)相关命令. hash 是一个string类型的field和value的映射表,特别适合用于存储对象. 序号 命令 描述 实例 返回 HSET ...
- ASP.NET MVC下Bundle的使用
ASP.NET MVC中Bundle是用于打包捆绑资源的(一般是css和js),它是在全局文件Global.asax.cs中注册Bundle,而注册的具体实现默认是在App_Start文件夹的Bund ...
- [翻译] REMenu
REMenu https://github.com/romaonthego/REMenu Dropdown menu inspired by Vine. 一款下拉菜单效果控件,灵感来自于Vine. R ...
- Python 系统学习梳理_【All】
Python学习 1. Python学习---Python安装与基础1205 2. Python学习---PyCharm的使用学习 3. Python学习---Python数据类型1206 4. Py ...
- 开发一个shopify插件
开发一个shopify插件,shopify商城可以安装该插件:当用户在商城下单后,插件把订单数据按照指定格式传给disruptsports服务器: https://help.shopify. ...
- Alpha 冲刺报告(9/10)
Alpha 冲刺报告(9/10) 队名:洛基小队 峻雄(组长) 已完成:角色属性功能的测试版 明日计划:准备α版本的ppt 剩余任务:尽量完成角色属性功能 困难:缺乏编程经验,很难自己独立完成编写,只 ...