Better file close and err handling

Signed-off-by: Mario Loriedo <mario.loriedo@gmail.com>
This commit is contained in:
Mario Loriedo
2024-02-25 21:04:56 +01:00
parent ea4553d590
commit f099250beb
14 changed files with 95 additions and 30 deletions

View File

@ -111,11 +111,17 @@ func Test_Decompress(t *testing.T) {
want want want want
}{ }{
{name: "zip", args: args{src: "./testdata/sample.zip", dst: "./testdata/hellozip"}, want: "zip\n"}, {name: "zip", args: args{src: "./testdata/sample.zip", dst: "./testdata/hellozip"}, want: "zip\n"},
{name: "zip with trailing zeros", args: args{src: "./testdata/sample-withzeros.zip", dst: "./testdata/hellozip-withzeros"}, want: "zip\n\x00\x00\x00\x00\x00\x00"},
{name: "xz", args: args{src: "./testdata/sample.xz", dst: "./testdata/helloxz"}, want: "xz\n"}, {name: "xz", args: args{src: "./testdata/sample.xz", dst: "./testdata/helloxz"}, want: "xz\n"},
{name: "xz with trailing zeros", args: args{src: "./testdata/sample-withzeros.xz", dst: "./testdata/helloxz-withzeros"}, want: "xz\n\x00\x00\x00\x00\x00\x00\x00"},
{name: "gzip", args: args{src: "./testdata/sample.gz", dst: "./testdata/hellogz"}, want: "gzip\n"}, {name: "gzip", args: args{src: "./testdata/sample.gz", dst: "./testdata/hellogz"}, want: "gzip\n"},
{name: "gzip with trailing zeros", args: args{src: "./testdata/sample-withzeros.gz", dst: "./testdata/hellogzip-withzeros"}, want: "gzip\n\x00\x00\x00\x00\x00"},
{name: "bzip2", args: args{src: "./testdata/sample.bz2", dst: "./testdata/hellobz2"}, want: "bzip2\n"}, {name: "bzip2", args: args{src: "./testdata/sample.bz2", dst: "./testdata/hellobz2"}, want: "bzip2\n"},
{name: "bzip2 with trailing zeros", args: args{src: "./testdata/sample-withzeros.bz2", dst: "./testdata/hellobz2-withzeros"}, want: "bzip2\n\x00\x00\x00\x00"},
{name: "zstd", args: args{src: "./testdata/sample.zst", dst: "./testdata/hellozstd"}, want: "zstd\n"}, {name: "zstd", args: args{src: "./testdata/sample.zst", dst: "./testdata/hellozstd"}, want: "zstd\n"},
{name: "uncompressed", args: args{src: "./testdata/sample.uncompressed", dst: "./testdata/hellozuncompressed"}, want: "uncompressed\n"}, {name: "zstd with trailing zeros", args: args{src: "./testdata/sample-withzeros.zst", dst: "./testdata/hellozstd-withzeros"}, want: "zstd\n\x00\x00\x00\x00\x00"},
{name: "uncompressed", args: args{src: "./testdata/sample.uncompressed", dst: "./testdata/hellouncompressed"}, want: "uncompressed\n"},
{name: "uncompressed with trailing zeros", args: args{src: "./testdata/sample-withzeros.uncompressed", dst: "./testdata/hellozuncompressed-withzeros"}, want: "uncompressed\n\x00\x00\x00\x00\x00\x00\x00"},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View File

@ -10,10 +10,9 @@ import (
) )
type genericDecompressor struct { type genericDecompressor struct {
compressedFilePath string compressedFilePath string
compressedFile *os.File compressedFile *os.File
decompressedFileReader io.ReadCloser compressedFileInfo os.FileInfo
compressedFileInfo os.FileInfo
} }
func newGenericDecompressor(compressedFilePath string) (*genericDecompressor, error) { func newGenericDecompressor(compressedFilePath string) (*genericDecompressor, error) {
@ -49,7 +48,11 @@ func (d *genericDecompressor) decompress(w WriteSeekCloser, r io.Reader) error {
if err != nil { if err != nil {
return err return err
} }
d.decompressedFileReader = decompressedFileReader defer func() {
if err := decompressedFileReader.Close(); err != nil {
logrus.Errorf("Unable to close gz file: %q", err)
}
}()
_, err = io.Copy(w, decompressedFileReader) _, err = io.Copy(w, decompressedFileReader)
return err return err
@ -59,10 +62,4 @@ func (d *genericDecompressor) close() {
if err := d.compressedFile.Close(); err != nil { if err := d.compressedFile.Close(); err != nil {
logrus.Errorf("Unable to close compressed file: %q", err) logrus.Errorf("Unable to close compressed file: %q", err)
} }
if d.decompressedFileReader != nil {
if err := d.decompressedFileReader.Close(); err != nil {
logrus.Errorf("Unable to close uncompressed stream: %q", err)
}
}
} }

View File

@ -9,12 +9,11 @@ import (
type gzipDecompressor struct { type gzipDecompressor struct {
genericDecompressor genericDecompressor
gzReader io.ReadCloser
} }
func newGzipDecompressor(compressedFilePath string) (*gzipDecompressor, error) { func newGzipDecompressor(compressedFilePath string) (*gzipDecompressor, error) {
d, err := newGenericDecompressor(compressedFilePath) d, err := newGenericDecompressor(compressedFilePath)
return &gzipDecompressor{*d, nil}, err return &gzipDecompressor{*d}, err
} }
func (d *gzipDecompressor) decompress(w WriteSeekCloser, r io.Reader) error { func (d *gzipDecompressor) decompress(w WriteSeekCloser, r io.Reader) error {
@ -22,16 +21,19 @@ func (d *gzipDecompressor) decompress(w WriteSeekCloser, r io.Reader) error {
if err != nil { if err != nil {
return err return err
} }
d.gzReader = gzReader defer func() {
if err := gzReader.Close(); err != nil {
logrus.Errorf("Unable to close gz file: %q", err)
}
}()
sparseWriter := NewSparseWriter(w) sparseWriter := NewSparseWriter(w)
defer func() {
if err := sparseWriter.Close(); err != nil {
logrus.Errorf("Unable to close uncompressed file: %q", err)
}
}()
_, err = io.Copy(sparseWriter, gzReader) _, err = io.Copy(sparseWriter, gzReader)
return err return err
} }
func (d *gzipDecompressor) close() {
if err := d.gzReader.Close(); err != nil {
logrus.Errorf("Unable to close gz file: %q", err)
}
d.genericDecompressor.close()
}

View File

@ -0,0 +1,51 @@
#!/bin/bash
echo "zstd" > hellozstd-withzeros && \
truncate -c -s 10 hellozstd-withzeros && \
zstd -f --sparse hellozstd-withzeros -o sample-withzeros.zst && \
rm hellozstd-withzeros
echo "zstd" > hellozstd && \
zstd -f --sparse hellozstd -o sample.zst && \
rm hellozstd
echo "gzip" > hellogzip-withzeros && \
truncate -c -s 10 hellogzip-withzeros && \
gzip -f -c hellogzip-withzeros > sample-withzeros.gz && \
rm hellogzip-withzeros
echo "gzip" > hellogzip && \
gzip -f -c hellogzip > sample.gz && \
rm hellogzip
echo "bzip2" > hellobzip2-withzeros && \
truncate -c -s 10 hellobzip2-withzeros && \
bzip2 -f -c hellobzip2-withzeros > sample-withzeros.bz2 && \
rm hellobzip2-withzeros
echo "bzip2" > hellobzip2 && \
bzip2 -f -c hellobzip2 > sample.bz2 && \
rm hellobzip2
echo "uncompressed" > sample-withzeros.uncompressed && \
truncate -c -s 20 sample-withzeros.uncompressed
echo "uncompressed" > sample.uncompressed
echo "xz" > helloxz-withzeros && \
truncate -c -s 10 helloxz-withzeros && \
xz -f -z -c helloxz-withzeros > sample-withzeros.xz && \
rm helloxz-withzeros
echo "xz" > helloxz && \
xz -f -z -c helloxz > sample.xz && \
rm helloxz
echo "zip" > hellozip-withzeros && \
truncate -c -s 10 hellozip-withzeros && \
zip sample-withzeros.zip hellozip-withzeros && \
rm hellozip-withzeros
echo "zip" > hellozip && \
zip sample.zip hellozip && \
rm hellozip

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,6 +2,8 @@ package compression
import ( import (
"io" "io"
"github.com/sirupsen/logrus"
) )
type uncompressedDecompressor struct { type uncompressedDecompressor struct {
@ -15,6 +17,12 @@ func newUncompressedDecompressor(compressedFilePath string) (*uncompressedDecomp
func (d *uncompressedDecompressor) decompress(w WriteSeekCloser, r io.Reader) error { func (d *uncompressedDecompressor) decompress(w WriteSeekCloser, r io.Reader) error {
sparseWriter := NewSparseWriter(w) sparseWriter := NewSparseWriter(w)
defer func() {
if err := sparseWriter.Close(); err != nil {
logrus.Errorf("Unable to close uncompressed file: %q", err)
}
}()
_, err := io.Copy(sparseWriter, r) _, err := io.Copy(sparseWriter, r)
return err return err
} }

View File

@ -4,16 +4,16 @@ import (
"io" "io"
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
"github.com/sirupsen/logrus"
) )
type zstdDecompressor struct { type zstdDecompressor struct {
genericDecompressor genericDecompressor
zstdReader *zstd.Decoder
} }
func newZstdDecompressor(compressedFilePath string) (*zstdDecompressor, error) { func newZstdDecompressor(compressedFilePath string) (*zstdDecompressor, error) {
d, err := newGenericDecompressor(compressedFilePath) d, err := newGenericDecompressor(compressedFilePath)
return &zstdDecompressor{*d, nil}, err return &zstdDecompressor{*d}, err
} }
func (d *zstdDecompressor) decompress(w WriteSeekCloser, r io.Reader) error { func (d *zstdDecompressor) decompress(w WriteSeekCloser, r io.Reader) error {
@ -21,14 +21,15 @@ func (d *zstdDecompressor) decompress(w WriteSeekCloser, r io.Reader) error {
if err != nil { if err != nil {
return err return err
} }
d.zstdReader = zstdReader defer zstdReader.Close()
sparseWriter := NewSparseWriter(w) sparseWriter := NewSparseWriter(w)
defer func() {
if err := sparseWriter.Close(); err != nil {
logrus.Errorf("Unable to close uncompressed file: %q", err)
}
}()
_, err = io.Copy(sparseWriter, zstdReader) _, err = io.Copy(sparseWriter, zstdReader)
return err return err
} }
func (d *zstdDecompressor) close() {
d.zstdReader.Close()
d.genericDecompressor.close()
}