Skip to content

Commit 60c03f0

Browse files
committed
Use mmap in ReadAll if possible
1 parent 3650e5c commit 60c03f0

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

excelize.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func (f *File) checkOpenReaderOptions() error {
175175
// OpenReader read data stream from io.Reader and return a populated
176176
// spreadsheet file.
177177
func OpenReader(r io.Reader, opts ...Options) (*File, error) {
178-
b, err := io.ReadAll(r)
178+
b, err := readAll(r)
179179
if err != nil {
180180
return nil, err
181181
}

lib.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (f *File) readBytes(name string) []byte {
118118
if err != nil {
119119
return content
120120
}
121-
content, _ = io.ReadAll(file)
121+
content, _ = readAll(file)
122122
f.Pkg.Store(name, content)
123123
_ = file.Close()
124124
return content

lib_nonwindows.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//go:build !windows
2+
3+
// Copyright 2025 The excelize Authors. All rights reserved. Use of
4+
// this source code is governed by a BSD-style license that can be found in
5+
// the LICENSE file.
6+
7+
package excelize
8+
9+
import (
10+
"io"
11+
"os"
12+
"runtime"
13+
"syscall"
14+
)
15+
16+
// readAll is like io.ReadAll, but uses mmap if possible.
17+
func readAll(r io.Reader) ([]byte, error) {
18+
if fder, ok := r.(interface {
19+
Fd() int
20+
Stat() (os.FileInfo, error)
21+
}); ok {
22+
if fi, err := fder.Stat(); err == nil {
23+
if b, err := syscall.Mmap(fder.Fd(), 0, int(fi.Size()),
24+
syscall.PROT_READ,
25+
syscall.MAP_PRIVATE|syscall.MAP_POPULATE,
26+
); err == nil {
27+
runtime.SetFinalizer(&b, func(_ any) error {
28+
return syscall.Munmap(b)
29+
})
30+
return b, nil
31+
}
32+
}
33+
}
34+
return io.ReadAll(r)
35+
}

lib_windows.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//go:build windows
2+
3+
// Copyright 2025 The excelize Authors. All rights reserved. Use of
4+
// this source code is governed by a BSD-style license that can be found in
5+
// the LICENSE file.
6+
7+
package excelize
8+
9+
import (
10+
"io"
11+
)
12+
13+
// readAll is like io.ReadAll, but uses mmap if possible.
14+
func readAll(r io.Reader) ([]byte, error) {
15+
return io.ReadAll(r)
16+
}

0 commit comments

Comments
 (0)