From bc6c1bf2099365ecddc4e3e95f46c79bf0f5a483 Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Mon, 3 Aug 2020 22:01:51 +0300 Subject: [PATCH 1/3] HW7 is completed --- hw07_file_copying/copy.go | 81 +++++++++++++++++++++++++++++++++- hw07_file_copying/copy_test.go | 17 ++++++- hw07_file_copying/go.mod | 7 ++- hw07_file_copying/go.sum | 28 ++++++++++++ hw07_file_copying/main.go | 7 ++- 5 files changed, 135 insertions(+), 5 deletions(-) diff --git a/hw07_file_copying/copy.go b/hw07_file_copying/copy.go index d9cb09a..82fa9f1 100644 --- a/hw07_file_copying/copy.go +++ b/hw07_file_copying/copy.go @@ -2,14 +2,93 @@ package main import ( "errors" + "fmt" + "io" + "os" + + "github.com/cheggaaa/pb/v3" ) var ( + ErrFileNotExist = errors.New("file doesn't exist") ErrUnsupportedFile = errors.New("unsupported file") ErrOffsetExceedsFileSize = errors.New("offset exceeds file size") ) func Copy(fromPath string, toPath string, offset, limit int64) error { - // Place your code here + err := fileErrors(fromPath, offset) + if err != nil { + return err + } + + // use limited reader instead default reader + limit = changeZeroLimit(fromPath, limit) + limitedReader, err := defineLimitedReader(fromPath, offset, limit) + if err != nil { + return err + } + + // define bar reader + bar := pb.Full.Start64(limit) + defer bar.Finish() + barReader := bar.NewProxyReader(limitedReader) + + // define default writer + writer, err := os.Create(toPath) + if err != nil { + return err + } + + _, err = io.Copy(writer, barReader) + if err != nil { + return err + } + + return nil +} + +func fileErrors(fromPath string, offset int64) error { + fileSt, err := os.Stat(fromPath) + if os.IsNotExist(err) { + return ErrFileNotExist + } + // check other errors + if err != nil { + return err + } + + fileSize := fileSt.Size() + fmt.Println(fileSize) + if fileSize < 0 { + return ErrUnsupportedFile + } + if offset > fileSize { + return ErrOffsetExceedsFileSize + } + return nil } + +func changeZeroLimit(fromPath string, limit int64) int64 { + fileSt, _ := os.Stat(fromPath) + + if limit < 1 { + limit = fileSt.Size() + } + + return limit +} + +func defineLimitedReader(fromPath string, offset, limit int64) (io.Reader, error) { + reader, err := os.Open(fromPath) + if err != nil { + return reader, err + } + _, err = reader.Seek(offset, io.SeekStart) + if err != nil { + return reader, err + } + + limitedReader := io.LimitReader(reader, limit) + return limitedReader, nil +} diff --git a/hw07_file_copying/copy_test.go b/hw07_file_copying/copy_test.go index b039d9e..46f0c4e 100644 --- a/hw07_file_copying/copy_test.go +++ b/hw07_file_copying/copy_test.go @@ -1,7 +1,20 @@ package main -import "testing" +import ( + "math" + "testing" + + "github.com/stretchr/testify/require" +) func TestCopy(t *testing.T) { - // Place your code here + t.Run("Check not exists file", func(t *testing.T) { + err := Copy("not-exist-file", "", 0, 0) + require.Equal(t, err, ErrFileNotExist) + }) + + t.Run("Too long offset", func(t *testing.T) { + err := Copy("testdata/input.txt", "", int64(math.Exp2(20)), 0) + require.Equal(t, err, ErrOffsetExceedsFileSize) + }) } diff --git a/hw07_file_copying/go.mod b/hw07_file_copying/go.mod index 15fbeb6..5542d65 100644 --- a/hw07_file_copying/go.mod +++ b/hw07_file_copying/go.mod @@ -1,3 +1,8 @@ -module github.com/fixme_my_friend/hw07_file_copying +module github.com/ezhk/golang-learning/hw07_file_copying go 1.14 + +require ( + github.com/cheggaaa/pb/v3 v3.0.4 + github.com/stretchr/testify v1.6.1 +) diff --git a/hw07_file_copying/go.sum b/hw07_file_copying/go.sum index e69de29..c4c0af0 100644 --- a/hw07_file_copying/go.sum +++ b/hw07_file_copying/go.sum @@ -0,0 +1,28 @@ +github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= +github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= +github.com/cheggaaa/pb v1.0.28 h1:kWGpdAcSp3MxMU9CCHOwz/8V0kCHN4+9yQm2MzWuI98= +github.com/cheggaaa/pb v2.0.7+incompatible h1:gLKifR1UkZ/kLkda5gC0K6c8g+jU2sINPtBeOiNlMhU= +github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM= +github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= +github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hw07_file_copying/main.go b/hw07_file_copying/main.go index 86c96cb..e9c66ba 100644 --- a/hw07_file_copying/main.go +++ b/hw07_file_copying/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "log" ) var ( @@ -18,5 +19,9 @@ func init() { func main() { flag.Parse() - // Place your code here + + err := Copy(from, to, offset, limit) + if err != nil { + log.Fatal(err) + } } From 8039f5fd7a413ddcc9dc84dfd5bd482b6e0498fd Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Mon, 3 Aug 2020 22:05:39 +0300 Subject: [PATCH 2/3] update linter checks --- hw07_file_copying/copy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw07_file_copying/copy.go b/hw07_file_copying/copy.go index 82fa9f1..136fa08 100644 --- a/hw07_file_copying/copy.go +++ b/hw07_file_copying/copy.go @@ -88,7 +88,7 @@ func defineLimitedReader(fromPath string, offset, limit int64) (io.Reader, error if err != nil { return reader, err } - limitedReader := io.LimitReader(reader, limit) + return limitedReader, nil } From 71136ff2432e2e41432b8da9b9218f21e8ddbd0e Mon Sep 17 00:00:00 2001 From: Andrey Kiselev Date: Thu, 13 Aug 2020 12:58:49 +0300 Subject: [PATCH 3/3] review updates --- hw07_file_copying/copy.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hw07_file_copying/copy.go b/hw07_file_copying/copy.go index 136fa08..e1943cf 100644 --- a/hw07_file_copying/copy.go +++ b/hw07_file_copying/copy.go @@ -2,7 +2,6 @@ package main import ( "errors" - "fmt" "io" "os" @@ -23,7 +22,7 @@ func Copy(fromPath string, toPath string, offset, limit int64) error { // use limited reader instead default reader limit = changeZeroLimit(fromPath, limit) - limitedReader, err := defineLimitedReader(fromPath, offset, limit) + limitedReader, err := openLimitedReader(fromPath, offset, limit) if err != nil { return err } @@ -32,12 +31,14 @@ func Copy(fromPath string, toPath string, offset, limit int64) error { bar := pb.Full.Start64(limit) defer bar.Finish() barReader := bar.NewProxyReader(limitedReader) + defer barReader.Close() // define default writer writer, err := os.Create(toPath) if err != nil { return err } + defer writer.Close() _, err = io.Copy(writer, barReader) if err != nil { @@ -58,7 +59,6 @@ func fileErrors(fromPath string, offset int64) error { } fileSize := fileSt.Size() - fmt.Println(fileSize) if fileSize < 0 { return ErrUnsupportedFile } @@ -70,7 +70,11 @@ func fileErrors(fromPath string, offset int64) error { } func changeZeroLimit(fromPath string, limit int64) int64 { - fileSt, _ := os.Stat(fromPath) + fileSt, err := os.Stat(fromPath) + // stay limit unchanged if stat caught error + if err != nil { + return limit + } if limit < 1 { limit = fileSt.Size() @@ -79,11 +83,12 @@ func changeZeroLimit(fromPath string, limit int64) int64 { return limit } -func defineLimitedReader(fromPath string, offset, limit int64) (io.Reader, error) { +func openLimitedReader(fromPath string, offset, limit int64) (io.Reader, error) { reader, err := os.Open(fromPath) if err != nil { return reader, err } + _, err = reader.Seek(offset, io.SeekStart) if err != nil { return reader, err