为了账号安全,请及时绑定邮箱和手机立即绑定

最近复制的文件将所有 0 作为字节数组返回

最近复制的文件将所有 0 作为字节数组返回

Go
慕无忌1623718 2022-05-23 17:19:24
我有一个 go 文件服务器,可以接收最大 10GB 的文件请求。为了保持低内存使用率,我将多部分表单数据读入 tmp 文件。我知道 FormFile 在幕后也是如此,但我仍然需要将其传输到常规文件以进行一些上传后处理。    f, header, err := r.FormFile("file")    if err != nil {        return nil, fmt.Errorf("could not get file from request %w", err)    }    tmpFile, err := ioutil.TempFile("", "oriio-")    if err != nil {        return nil, err    }    if _, err := io.Copy(tmpFile, f); err != nil {        return nil, fmt.Errorf("could not copy request body to file %w", err)    }在此之后,我需要获取文件的前 261 个字节以确定它的 MIME 类型。head := make([]byte, 261)if _, err := tmpFile.Read(head); err != nil {  return nil, err}我遇到的问题是,如果我尝试直接从 tmpFile 读取字节数组在我打印fmt.Prinf("%x", head)又名无效数据时返回 261 0。为了验证数据是否有效,我将其保存到在我的系统中打开它的常规文件中,并且该文件(在本例中为图像文件)完美无缺。所以这不是文件损坏的问题。为了解决这个问题,我现在关闭了 tmp 文件,然后再次重新打开它,这似乎可以解决所有问题。    tmpFile, err := ioutil.TempFile("", "oriio-")    if err != nil {        return nil, err    }    if _, err := io.Copy(tmpFile, f); err != nil {        return nil, fmt.Errorf("could not copy request body to file %w", err)    }    tmpFile.Close()    tmpFile, err = os.Open(tmpFile.Name())    if err != nil {        panic(err)    }    head := make([]byte, 261)    if _, err := tmpFile.Read(head); err != nil {        return nil, err    }现在,当我打印出头字节数组时,就会打印出正确的内容。为什么是这样?我必须对原始 tmp 文件进行某种同步或刷新以使其工作吗?去
查看完整描述

1 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

读取/写入文件会更改文件中的当前位置。复制后,tmpFile位于末尾,因此从中读取将读取 0 个字节。如果要从文件开头读取,则必须先查找:


io.Copy(tmpFile, f)

tmpFile.Seek(0,0)

tmpFile.Read(head)


查看完整回答
反对 回复 2022-05-23
  • 1 回答
  • 0 关注
  • 136 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号