diff --git a/file.go b/file.go index c5ccff53db..26ad3504e8 100644 --- a/file.go +++ b/file.go @@ -87,22 +87,23 @@ func (f *File) SaveAs(name string, opts ...Options) error { // Close closes and cleanup the open temporary file for the spreadsheet. func (f *File) Close() error { - var err error + var firstErr error if f.sharedStringTemp != nil { - if err := f.sharedStringTemp.Close(); err != nil { - return err - } + firstErr = f.sharedStringTemp.Close() + f.sharedStringTemp = nil + } + for _, stream := range f.streams { + _ = stream.rawData.Close() } + f.streams = nil f.tempFiles.Range(func(k, v interface{}) bool { - if err = os.Remove(v.(string)); err != nil { - return false + if err := os.Remove(v.(string)); err != nil && firstErr == nil { + firstErr = err } return true }) - for _, stream := range f.streams { - _ = stream.rawData.Close() - } - return err + f.tempFiles.Clear() + return firstErr } // Write provides a function to write to an io.Writer. diff --git a/file_test.go b/file_test.go index 4a9b5eaa22..58c9e4a265 100644 --- a/file_test.go +++ b/file_test.go @@ -7,6 +7,7 @@ import ( "math" "os" "path/filepath" + "strconv" "strings" "sync" "testing" @@ -164,3 +165,24 @@ func TestZip64(t *testing.T) { assert.NoError(t, f.Close()) }) } + +func TestRemoveTempFiles(t *testing.T) { + tmp, err := os.CreateTemp("", "excelize-*") + if err != nil { + t.Fatal(err) + } + tmpName := tmp.Name() + tmp.Close() + f := NewFile() + // fill the tempFiles map with non-existing (erroring on Remove) "files" + for i := 0; i < 1000; i++ { + f.tempFiles.Store(strconv.Itoa(i), "/hopefully not existing") + } + f.tempFiles.Store("existing", tmpName) + + require.Error(t, f.Close()) + if _, err := os.Stat(tmpName); err == nil { + t.Errorf("temp file %q still exist", tmpName) + os.Remove(tmpName) + } +} diff --git a/lib.go b/lib.go index e06e7f5105..113d574fbf 100644 --- a/lib.go +++ b/lib.go @@ -80,7 +80,7 @@ func (f *File) ReadZipReader(r *zip.Reader) (map[string][]byte, int, error) { // unzipToTemp unzip the zip entity to the system temporary directory and // returned the unzipped file path. func (f *File) unzipToTemp(zipFile *zip.File) (string, error) { - tmp, err := os.CreateTemp(os.TempDir(), "excelize-") + tmp, err := os.CreateTemp("", "excelize-") if err != nil { return "", err } diff --git a/rows.go b/rows.go index 986eb4502d..fca3c68b20 100644 --- a/rows.go +++ b/rows.go @@ -139,8 +139,10 @@ func (rows *Rows) Error() error { // Close closes the open worksheet XML file in the system temporary // directory. func (rows *Rows) Close() error { - if rows.tempFile != nil { - return rows.tempFile.Close() + tempFile := rows.tempFile + rows.tempFile = nil + if tempFile != nil { + return tempFile.Close() } return nil } @@ -366,7 +368,7 @@ func (f *File) getFromStringItem(index int) string { }() } f.sharedStringItem = [][]uint{} - f.sharedStringTemp, _ = os.CreateTemp(os.TempDir(), "excelize-") + f.sharedStringTemp, _ = os.CreateTemp("", "excelize-") f.tempFiles.Store(defaultTempFileSST, f.sharedStringTemp.Name()) var ( inElement string diff --git a/stream.go b/stream.go index 392d046bde..63309ff3bd 100644 --- a/stream.go +++ b/stream.go @@ -775,7 +775,7 @@ func (bw *bufferedWriter) Sync() (err error) { return nil } if bw.tmp == nil { - bw.tmp, err = os.CreateTemp(os.TempDir(), "excelize-") + bw.tmp, err = os.CreateTemp("", "excelize-") if err != nil { // can not use local storage return nil