使用part.Read读取每个块超过4096个字节

时间:2018-02-06 13:52:54

标签: go

我试图以小块的形式处理多部分文件上传,以避免将整个文件存储在内存中。以下函数似乎解决了这个问题,但是当传递[]byte作为part.Read()方法的目标时,它以4096字节的块的形式读取部分而不是目标大小的块({{1 }})。

打开本地文件并len([]byte)将其转换为相同大小的Read()时,它会按预期使用整个可用空间。因此,我认为这是[]byte特有的。但是,我无法找到有关该功能的默认或最大尺寸的任何内容。

供参考,功能如下:

part.Reader()

2 个答案:

答案 0 :(得分:1)

而是更改块大小,为什么不使用io.ReadFull

https://golang.org/pkg/io/#ReadFull

这可以管理整个逻辑,如果无法读取它只会返回错误。

答案 1 :(得分:1)

部分阅读器不会尝试填充io.Reader合同允许的来电者的缓冲区。

处理此问题的最佳方法取决于应用程序的要求。

如果您想将部分啜饮到内存中,请使用ioutil.ReadAll

for {
    part, err := reader.NextPart()
    if err == io.EOF {
      break
    }
    if err != nil {
      // handle error
    }
    p, err := ioutil.ReadAll(part)
    if err != nil {
      // handle error
    }
    // p is []byte with the contents of the part
}

如果您要将零件复制到io.Writer w,请使用io.Copy

for {
    part, err := reader.NextPart()
    if err == io.EOF {
      break
    }
    if err != nil {
      // handle error
    }
    w := // open a writer
    _, err := io.Copy(w, part)
    if err != nil {
      // handle error
    }
}

如果要处理固定大小的块,请使用io.ReadFull

 buf := make([]byte, chunkSize)
 for {
    part, err := reader.NextPart()
    if err == io.EOF {
      break
    }
    if err != nil {
      // handle error
    }
    _, err := io.ReadFull(part, buf)
    if err != nil {
      // handle error
      // Note that ReadFull returns an error if it cannot fill buf
    }
    // process the next chunk in buf
}

如果应用程序数据的结构不是修复大小的块,那么bufio.Scanner可能会有所帮助。