From 97a7408481816d46bff313096ee6c229784ed9bb Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Thu, 15 Jan 2026 15:52:41 +0100 Subject: [PATCH] file-util.go: new functions CopyFileWithParent(), CopyFile(), CompareFilesBMd5(), CompareLastChangeTime(), and LoadFile() --- file-util.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/file-util.go b/file-util.go index fba6f0a..e297ba3 100644 --- a/file-util.go +++ b/file-util.go @@ -5,10 +5,13 @@ package utils import ( + "bytes" + "crypto/md5" "errors" "fmt" "io" "os" + "path" "strconv" "strings" ) @@ -140,3 +143,104 @@ func ParseMemSize(s string) (size int64, err error) { } return } + +func CopyFileWithParent(src, dst string, perm os.FileMode) (int64, error) { + parent := path.Dir(dst) + if err := os.MkdirAll(parent, 0775); err != nil { + return 0, err + } + return CopyFile(src, dst, perm) +} + +func CopyFile(src, dst string, perm os.FileMode) (int64, error) { + sourceFileStat, err := os.Stat(src) + if err != nil { + return 0, err + } + + if !sourceFileStat.Mode().IsRegular() { + return 0, fmt.Errorf("%s is not a regular file", src) + } + + source, err := os.Open(src) + if err != nil { + return 0, err + } + defer source.Close() + + destination, err := os.Create(dst) + if err != nil { + return 0, err + } + defer destination.Close() + + if perm != 0 { + os.Chmod(dst, perm) + } + nBytes, err := io.Copy(destination, source) + return nBytes, err +} + +func CompareFilesByMd5(filePath1, filePath2 string) (same bool, err error) { + var fh1, fh2 *os.File + + if fh1, err = os.Open(filePath1); err != nil { + return + } + defer fh1.Close() + + if fh2, err = os.Open(filePath2); err != nil { + return + } + defer fh2.Close() + + h1 := md5.New() + if _, err = io.Copy(h1, fh1); err != nil { + return + } + + h2 := md5.New() + if _, err = io.Copy(h2, fh2); err != nil { + return + } + + s1 := h1.Sum(nil) + s2 := h2.Sum(nil) + same = bytes.Equal(s1, s2) + // same = bytes.Equal(h1.Sum(nil), h2.Sum(nil)) + return +} + +// <0 = first newer than second +// =0 = same date +// >1 = first older than second +func CompareLastChangeTime(first, second string) (result int, err error) { + var info os.FileInfo + + if info, err = os.Stat(first); err != nil { + return + } + + if info, err = os.Stat(second); err != nil { + return + } + + tFirst := info.ModTime() + tSecond := info.ModTime() + if tFirst.After(tSecond) { + result = -1 + } else if tFirst.Before(tSecond) { + result = 1 + } else { + result = 0 + } + return +} + +func LoadFile(filePath string) (data []byte, err error) { + data, err = os.ReadFile(filePath) + if err != nil { + err = fmt.Errorf("error reading file %q: %w", filePath, err) + } + return +}