-
Notifications
You must be signed in to change notification settings - Fork 0
HW7 is completed #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,14 +2,98 @@ package main | |
|
|
||
| import ( | ||
| "errors" | ||
| "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 := openLimitedReader(fromPath, offset, limit) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // define bar reader | ||
| 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 { | ||
| 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() | ||
| if fileSize < 0 { | ||
| return ErrUnsupportedFile | ||
| } | ||
| if offset > fileSize { | ||
| return ErrOffsetExceedsFileSize | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func changeZeroLimit(fromPath string, limit int64) int64 { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. А может ли быть вариант, когда
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Внутри openLimitedReader есть проверка на offset, а limit не может быть больше FileSize.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. limit задаётся как внешний параметр, его можно задать и больше чем FileSize, не вижу где в работе проверяется это ограничение. |
||
| fileSt, err := os.Stat(fromPath) | ||
| // stay limit unchanged if stat caught error | ||
| if err != nil { | ||
| return limit | ||
| } | ||
|
|
||
| if limit < 1 { | ||
| limit = fileSt.Size() | ||
| } | ||
|
|
||
| return limit | ||
| } | ||
|
|
||
| func openLimitedReader(fromPath string, offset, limit int64) (io.Reader, error) { | ||
| reader, err := os.Open(fromPath) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Файлы надо закрывать.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Закрываю в main сам reader. |
||
| 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 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) | ||
| }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше воспользоваться
io.CopyN().There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тогда нужно будет цикл делать?
Я ведь правильно понял, что цель — копировать небольшими «порциями»?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Он внутри копирует порциями.