V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
airplayxcom
V2EX  ›  Go 编程语言

强大的 v 友们,问个问题:怎样从第三方获取文件分片传递给前端 golang

  •  
  •   airplayxcom · 2020-01-19 00:35:21 +08:00 via iPhone · 3122 次点击
    这是一个创建于 1800 天前的主题,其中的信息可能已经有所发展或是发生改变。
    分片获取容易实现,怎么分片给前端呢?
    实现静态服务器的方式前提是后端形成了这个整体文件反给前端。我想做的是一边从源端获取一边反给前端。
    10 条回复    2020-01-20 02:12:22 +08:00
    BlackBerry999
        1
    BlackBerry999  
       2020-01-19 09:11:34 +08:00
    协程+channel ? 或者 socket ?
    Leigg
        2
    Leigg  
       2020-01-19 09:44:27 +08:00 via Android
    为何不让前端直接调用三方接口,减少故障点,是有什么经过后台的必要性?如果有,最好先缓存后台,缓存完成后再传前端,这样成功率更大些,大文件更甚。
    airplayxcom
        3
    airplayxcom  
    OP
       2020-01-19 10:10:51 +08:00 via iPhone
    @Leigg 是的 必须走后端授权,缓存大文件不吃内存吗,几个人同时下载发文件怎么办。
    puyo
        4
    puyo  
       2020-01-19 10:33:50 +08:00
    先 head 拿到 contentLength,返回头信息,然后并发去第三方下载,按顺序 flush。
    Leigg
        5
    Leigg  
       2020-01-19 14:23:28 +08:00 via Android
    @airplayxcom 缓存并不一定就是存内存。后台整一段磁盘空间用来缓存下载文件,只做临时缓存,下完就删,或者保留一段时间。
    index90
        6
    index90  
       2020-01-19 17:04:23 +08:00
    http.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) {
    file, err := os.Open("")
    if err != nil {
    writer.WriteHeader(404)
    return
    }
    defer file.Close()
    if _, err := io.Copy(writer, file); err != nil {
    writer.WriteHeader(500)
    return
    }
    writer.Header().Set("content-type", "text/plain")
    writer.WriteHeader(200)
    })
    index90
        7
    index90  
       2020-01-19 17:10:37 +08:00
    如果你不是读取本地文件,而是从别人的请求中转发数据,你留意一下 http.Response 的 body 是已经实现了 reader interface,只需要从 reader copy 数据到 writer 就可以了。

    面向接口编程,你需要什么接口,去找对应的实现就可以了。
    index90
        8
    index90  
       2020-01-19 17:26:23 +08:00   ❤️ 1
    #6 的代码不对,send header 应该在 send body 之前。
    http.HandleFunc("", func(writer http.ResponseWriter, request *http.Request) {
    var reader io.Reader
    //{
    // file, err := os.Open("")
    // if err != nil {
    // writer.WriteHeader( http.StatusNotFound)
    // return
    // }
    // reader = file
    // defer file.Close()
    //}
    {
    resp, err := http.Client{}.Get("")
    if err != nil {
    writer.WriteHeader( http.StatusNotFound)
    return
    }
    reader = resp.Body
    }
    writer.Header().Set("content-type", "text/plain")
    _, _ = io.Copy(writer, reader)
    return
    })
    airplayxcom
        9
    airplayxcom  
    OP
       2020-01-20 00:31:43 +08:00 via iPhone
    @index90 有心了
    ihciah
        10
    ihciah  
       2020-01-20 02:12:22 +08:00
    不一定非要先全拼出来,可以流式处理,具体实现可以按照楼上的直接用 Reader 接口。自己实现 Reader 接口的话,在 read 的时候现场拼接下一块返回就行了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3660 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:36 · PVG 18:36 · LAX 02:36 · JFK 05:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.