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

我有一个 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 文件进行某种同步或刷新以使其工作吗?



慕无忌1623718
浏览 137回答 1
1回答

温温酱

读取/写入文件会更改文件中的当前位置。复制后,tmpFile位于末尾,因此从中读取将读取 0 个字节。如果要从文件开头读取,则必须先查找:io.Copy(tmpFile, f)tmpFile.Seek(0,0)tmpFile.Read(head)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go