I have a folder named "myfolder" that has some txt and jpeg files and and a folder named "test". I want to copy files inside myfolder to test until it reaches a certain size, for example 10MB, then stop to copy.
This is my code that does not work:
package main
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
)
var (
MyFolderPath = "/home/jim/myfolder"
files []string
)
func copy(source []string, destination string) {
for a, b := range source {
input, _ := ioutil.ReadFile(b)
ioutil.WriteFile(destination+strconv.Itoa(a), input, 0777)
}
}
func CopyFile(path string) {
var size int64
done := errors.New("size reached")
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if err != nil {
return err
}
copy(files[1:], fmt.Sprintf("%v/test/%v", MyFolderPath, "file"))
size += info.Size()
if size > 10000 {
return done
}
return err
})
if err != nil {
fmt.Println(err)
}
}
func CollectFiles() {
err := filepath.Walk(MyFolderPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println(err)
}
files = append(files, path)
return nil
})
if err != nil {
fmt.Println(err)
}
}
func main() {
CollectFiles()
CopyFile(fmt.Sprintf("%v/test", MyFolderPath))
}
What I do wrong and how can I do in right way?
You have multiple places where you're wrong. Perhaps check this code and compare:
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
var (
MyFolderPath = "/tmp"
DestPath = "/tmp/dest"
CumulativeSize int64 = 0 // in bytes
ErrDone = errors.New("done")
)
const UpperLimit = 1024 * // 1 Kilobyte
1024 * // 1 Megabyte
10 // 10 Megabytes
func main() {
err := filepath.Walk(MyFolderPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Printf("problem with file (%s): %v", path, err)
return nil
}
if info.IsDir() {
return filepath.SkipDir // skip it, walk will enter it too
}
CumulativeSize += info.Size()
if CumulativeSize >= UpperLimit {
return ErrDone
}
// copy file here
return nil
})
if err == ErrDone {
fmt.Println("finished successfully")
} else {
fmt.Printf("error: %v", err)
}
}
This line is wrong:
copy(files[1:], fmt.Sprintf("%v/test/%v", MyFolderPath, "file"))
Every time you find a file match, you tell it to (re)-copy every file in your files
slice, except the first one.
You probably want to copy a single file there.
Although your code is difficult to reason through--I'm not sure why files
exists at all, nor why you're walking your directory structure twice. So your goals aren't really clear, so it's hard to be more specific.
Also note: You should not use copy
as the name of a function, as that is a built-in, so makes your code very confusing to read.