教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang实现http表单大文件流式上传服务端代码

golang实现http表单大文件流式上传服务端代码

发布时间:2022-01-06   编辑:jiaochengji.com
教程集为您提供golang实现http表单大文件流式上传服务端代码等资源,欢迎您收藏本站,我们将为您提供最新的golang实现http表单大文件流式上传服务端代码资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg>

<h3>golang实现http表单大文件流式上传服务端代码</h3>

golang的http标准库的上传文件是一次性将文件全部读到内存中,这样上传小文件还可以,但是大文件就无能为力了。
一开始在网上找到一篇gin实现大文件流式上传的文章。大体思路是手动解析form表单的header和body,然后分片读取上传的文件内容。但是代码量有点多且复杂。有兴趣的同学可以自行百度。

后来在github找到一个库
github.com/albrow/forms

可以看到这个库读取上传文件的方法

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token punctuation">(</span>d Data<span class="token punctuation">)</span> <span class="token function">GetFileBytes</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fileHeader<span class="token punctuation">,</span> found <span class="token operator">:=</span> d<span class="token punctuation">.</span>Files<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token keyword">if</span> <span class="token operator">!</span>found <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> file<span class="token punctuation">,</span> err <span class="token operator">:=</span> fileHeader<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err <span class="token punctuation">}</span> <span class="token keyword">return</span> ioutil<span class="token punctuation">.</span><span class="token function">ReadAll</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

最后使用的是ioutil.ReadAll,大文件上传的话就会有问题,要实现流式上传,可以在这个包里加一个方法。以下是我自己加的方法

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token punctuation">(</span>d Data<span class="token punctuation">)</span> <span class="token function">GetFileReader</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">(</span>io<span class="token punctuation">.</span>Reader<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> fileHeader<span class="token punctuation">,</span> found <span class="token operator">:=</span> d<span class="token punctuation">.</span>Files<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token keyword">if</span> <span class="token operator">!</span>found <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> file<span class="token punctuation">,</span> err <span class="token operator">:=</span> fileHeader<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err <span class="token punctuation">}</span> <span class="token keyword">return</span> file<span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

得到reader后使用io.Copy即可将文件落盘

<pre><code class="lang-go hljs"> userData<span class="token punctuation">,</span> err <span class="token operator">:=</span> forms<span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span>c<span class="token punctuation">.</span>Request<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"parse错误:%v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> header <span class="token operator">:=</span> userData<span class="token punctuation">.</span><span class="token function">GetFile</span><span class="token punctuation">(</span><span class="token string">"file"</span><span class="token punctuation">)</span> fileReader<span class="token punctuation">,</span> err <span class="token operator">:=</span> userData<span class="token punctuation">.</span><span class="token function">GetFileReader</span><span class="token punctuation">(</span><span class="token string">"file"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">"获取reader错误:%v"</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> file<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> os<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span>header<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span> io<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span> fileReader<span class="token punctuation">)</span> </code></pre> 到此这篇关于“golang实现http表单大文件流式上传服务端代码”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang基础第五篇——golang的gRPC
php输入流php://input发送图片流到服务器的例子
支持多语言的微服务框架Tars-Go
Golang 限流器的使用和实现
golang微服务框架对比_Golang 微服务教程(二)
golang微服务框架对比_最强开源微服务框架,全网独家整理
订阅redis接收的json字符串斜杠_用 Golang 实现基于 Redis 的安全高效 RPC 通信
云原生环境下微服务管理系统开发
golang微服务框架对比_Golang 中的微服务 - 第一部分
PHP5中使用Web服务访问J2EE应用程序(1)

[关闭]
~ ~