Skip to content

Commit

Permalink
HW07 is completed
Browse files Browse the repository at this point in the history
  • Loading branch information
DimVlas committed Jun 18, 2024
1 parent 88f0a3c commit 1f618fe
Show file tree
Hide file tree
Showing 6 changed files with 360 additions and 5 deletions.
Empty file removed hw07_file_copying/.sync
Empty file.
139 changes: 138 additions & 1 deletion hw07_file_copying/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package main

import (
"errors"
"fmt"
"io"
"os"
)

var (
Expand All @@ -10,6 +13,140 @@ var (
)

func Copy(fromPath, toPath string, offset, limit int64) error {
// Place your code here.
fromFile, fromSize, err := fileOpen(fromPath, offset)
if err != nil {
return fmt.Errorf("fromFileOpen: %w", err)
}
defer func() {
if fromFile == nil {
return
}
if err := fromFile.Close(); err != nil {
panic(err)
}
}()

toFile, err := fileCreate(toPath)
if err != nil {
return fmt.Errorf("toFileCreate: %w", err)
}
defer func() {
if toFile == nil {
return
}
if err := toFile.Close(); err != nil {
panic(err)
}
}()

copySize := fromSize - offset
if limit > 0 && limit < copySize {
copySize = limit
}

if offset > 0 {
_, err = fromFile.Seek(offset, 0)
if err != nil {
return err
}
}

err = copyRW(fromFile, toFile, copySize)
if err != nil {
return err
}

return nil
}

func fileOpen(fromPath string, offset int64) (*os.File, int64, error) {
file, err := os.Open(fromPath)
if err != nil {
return nil, 0, err
}

defer func() {
// закрыть файл, если ошибка
if err != nil {
if errCl := file.Close(); errCl != nil {
panic(errCl)
}
}
}()

fileInfo, err := file.Stat()
if err != nil {
return nil, 0, err
}

if !fileInfo.Mode().IsRegular() {
err = ErrUnsupportedFile
return nil, 0, err
}

size := fileInfo.Size()
if offset >= size {
err = ErrOffsetExceedsFileSize
return nil, 0, err
}

return file, size, nil
}

func fileCreate(toPath string) (*os.File, error) {
file, err := os.Create(toPath)
if err != nil {
return nil, err
}

defer func() {
// закрыть файл, если ошибка
if err != nil {
errCl := file.Close()
if errCl != nil {
panic(errCl)
}
}
}()

fileInfo, err := file.Stat()
if err != nil {
return nil, err
}

if !fileInfo.Mode().IsRegular() {
return nil, ErrUnsupportedFile
}

return file, nil
}

func copyRW(from io.Reader, to io.Writer, size int64) error {
var (
copySize int64 = 512 // кол-во байт копируемых за одну итерацию. из io.ReadAll
copied int64
)
if size < copySize {
copySize = size
}

// bar := pb.New64(size)

for i := size; i > 0; i -= copySize {
if i < copySize {
copySize = i
}

c, err := io.CopyN(to, from, copySize)
if err != nil {
return err
}
copied += c
fmt.Printf("\r%v%%", (100*copied)/size)
// bar.Add64(copySize)
}
fmt.Println()
// bar.Finish()

return nil
}
184 changes: 182 additions & 2 deletions hw07_file_copying/copy_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,187 @@
package main

import "testing"
import (
"fmt"
"log"
"os"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestCopy(t *testing.T) {
// Place your code here.
newFile, err := os.CreateTemp("./testdata/", "test_file_*.txt")
if err != nil {
panic(err)
}
defer func() {
os.Remove(newFile.Name())
}()

size, err := newFile.WriteString("Необходимо реализовать утилиту копирования файлов\n") // size = 95
if err != nil {
t.Error(err)
return
}

log.Println(size)

t.Run("no error full file", func(t *testing.T) {
toName := "./testdata/out_test_file.txt"
err := Copy(newFile.Name(), toName, 0, 0)

require.NoError(t, err)
require.FileExistsf(t, toName, "file must %v exists", toName)

toFile, _ := os.Open(toName)
toFileInfo, _ := toFile.Stat()
require.Equalf(t, int64(size), toFileInfo.Size(), "file size must be %v", size)

defer os.Remove(toFile.Name())
})

t.Run("no error size less limit", func(t *testing.T) {
toName := "./testdata/out_test_file.txt"
err := Copy(newFile.Name(), toName, 90, 30)

require.NoError(t, err)
require.FileExistsf(t, toName, "file must %v exists", toName)

toFile, _ := os.Open(toName)
toFileInfo, _ := toFile.Stat()
require.Equalf(t, int64(5), toFileInfo.Size(), "file size must be %v", 5)

defer os.Remove(toFile.Name())
})
}

func TestFileCreate(t *testing.T) {
t.Run("not regular file", func(t *testing.T) {
fromPath := "/dev/urandom"

toFile, tstErr := fileCreate(fromPath)
defer func() {
if toFile == nil {
return
}
errCl := toFile.Close()
if errCl != nil {
panic(errCl)
}
}()

require.EqualError(t, tstErr, ErrUnsupportedFile.Error(), "actual err - %v", tstErr)
require.Nil(t, toFile, "file must be nil")
})

t.Run("no error new file", func(t *testing.T) {
toPath := fmt.Sprintf("./testdata/out_test_create_%v.txt", time.DateTime)

toFile, tstErr := fileCreate(toPath)
defer func() {
if toFile == nil {
return
}

if errCl := toFile.Close(); errCl != nil {
panic(errCl)
}
if errRm := os.Remove(toFile.Name()); errRm != nil {
panic(errRm)
}
}()

require.NoError(t, tstErr)
require.NotNil(t, toFile, "file must not be nil")
})

t.Run("no error exist file", func(t *testing.T) {
newFile, err := os.CreateTemp("./testdata/", "out_test_create_*.txt")
if err != nil {
panic(err)
}
defer func() {
os.Remove(newFile.Name())
}()

toPath := newFile.Name()
toFile, tstErr := fileCreate(toPath)
defer func() {
if toFile == nil {
return
}
errCl := toFile.Close()
if errCl != nil {
panic(errCl)
}
}()

require.NoError(t, tstErr)
require.NotNil(t, toFile, "file must not be nil")
})
}

func TestFileOpen(t *testing.T) {
t.Run("not regular file", func(t *testing.T) {
var offset int64 = 1000

fromPath := "/dev/urandom"

fromFile, fromSize, tstErr := fileOpen(fromPath, offset)
defer func() {
if fromFile == nil {
return
}
errCl := fromFile.Close()
if errCl != nil {
panic(errCl)
}
}()

require.EqualError(t, tstErr, ErrUnsupportedFile.Error(), "actual err - %v", tstErr)
require.Nil(t, fromFile, "file must be nil")
require.Equal(t, fromSize, int64(0), "file size must be 0")
})

t.Run("big file", func(t *testing.T) {
var offset int64 = 1000
fromPath := "./testdata/out_offset6000_limit1000.txt"

fromFile, fromSize, tstErr := fileOpen(fromPath, offset)
defer func() {
if fromFile == nil {
return
}
errCl := fromFile.Close()
if errCl != nil {
panic(errCl)
}
}()

require.EqualError(t, tstErr, ErrOffsetExceedsFileSize.Error(), "actual err - %v", tstErr)
require.Nil(t, fromFile, "file must be nil")
require.Equal(t, fromSize, int64(0), "file size must be 0")
})

t.Run("no error", func(t *testing.T) {
var offset int64 = 100

fromPath := "./testdata/out_offset6000_limit1000.txt"

fromFile, fromSize, tstErr := fileOpen(fromPath, offset)
log.Println(fromSize)
defer func() {
if fromFile == nil {
return
}
errCl := fromFile.Close()
if errCl != nil {
panic(errCl)
}
}()
require.NoError(t, tstErr)
require.NotNil(t, fromFile, "file must not be nil")
require.Equalf(t, fromSize, int64(617), "file size must be %v", fromSize)
})
}
10 changes: 9 additions & 1 deletion hw07_file_copying/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
module github.com/fixme_my_friend/hw07_file_copying
module github.com/DimVlas/hw07_file_copying

go 1.19

require github.com/stretchr/testify v1.9.0

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 10 additions & 0 deletions hw07_file_copying/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
22 changes: 21 additions & 1 deletion hw07_file_copying/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"flag"
"fmt"
)

var (
Expand All @@ -18,5 +19,24 @@ func init() {

func main() {
flag.Parse()
// Place your code here.

// var (
// tt int64 = 1024
// i int64 = 0
// )
// pct := &pp.PctProgress{}
// pct.Start(tt)
// for ; i < tt; i += 10 {
// pct.Increment(10)
// time.Sleep(time.Second / 20)
// }

// pct.Finish()

// time.Sleep(time.Millisecond * 500)

if err := Copy(from, to, offset, limit); err != nil {
fmt.Println(err)
return
}
}

0 comments on commit 1f618fe

Please sign in to comment.