Efficiently read file by part in Go
September 10, 2023
Golang
Utilize allocated memory to efficiently read file by part in Go.
You can read text files line by line. Also you can read binary files part by part, especially when dealing with large files. The part size depends on your actual need. Let’s find out how to do this in Go.
Read file by part
A common case is uploading a very large file. You need to read in parts, then upload it to cloud storage. But read file into memory is a RAM consuming operation. So reuse the allocated memory is the key to be cost-effective.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package main import ( "fmt" "math" "os" ) func calculateTotalParts(size int64, partSize int32) int32 { var parts float64 parts = math.Ceil(float64(size) / float64(partSize)) return int32(parts) } const partSize = 1024 * 1024 * 16 // 16MiB func main() { var filePath = "" // fill in the file path inf, err := os.Stat(filePath) if err != nil { fmt.Println(err) return } file, err := os.Open(filePath) if err != nil { fmt.Println(err) return } var buf = make([]byte, partSize) var remaining = inf.Size() var part int32 = 0 var parts = calculateTotalParts(inf.Size(), partSize) for part < parts { rn, err := file.Read(buf) if err != nil { fmt.Println(err) return } // whatever to do with buf remaining = remaining - int64(rn) if remaining < partSize { buf = buf[:remaining] } part = part + 1 } } |
Line 33, allocate an array with fixed size.
Line 38, reuse the allocated memory.
Line 48, shrink the array size to fit to remaining bytes exactly.
I don’t provide examples in other languages, but the concept exists the same.