files
simple_backup/internal/copy/copy.go
2025-08-01 10:48:56 +09:00

72 lines
1.7 KiB
Go

package copy
import (
"fmt"
"io"
"os"
"sync"
"git.lhk.o-r.kr/freerer2/simple_backup/internal/constants"
)
var bufferPool = sync.Pool{
New: func() interface{} {
return make([]byte, constants.CopyBufferSize)
},
}
func RunCopy(srcFile, dstFile string) error {
// 소스 파일 정보 확인
srcInfo, err := os.Stat(srcFile)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("source file does not exist: %s", srcFile)
}
return fmt.Errorf("failed to get source file info: %w", err)
}
// 소스 파일 열기
src, err := os.Open(srcFile)
if err != nil {
return fmt.Errorf("failed to open source file: %w", err)
}
defer func() {
if cerr := src.Close(); cerr != nil && err == nil {
err = fmt.Errorf("failed to close source file: %w", cerr)
}
}()
// 대상 파일 생성
dst, err := os.Create(dstFile)
if err != nil {
return fmt.Errorf("failed to create destination file: %w", err)
}
defer func() {
if cerr := dst.Close(); cerr != nil && err == nil {
err = fmt.Errorf("failed to close destination file: %w", cerr)
}
}()
// 버퍼 풀에서 가져오기
buf := bufferPool.Get().([]byte)
defer bufferPool.Put(buf)
// 파일 내용 복사
if _, err = io.CopyBuffer(dst, src, buf); err != nil {
return fmt.Errorf("failed to copy file contents: %w", err)
}
// 파일 권한과 시간 정보 복사
if err := os.Chmod(dstFile, srcInfo.Mode()); err != nil {
return fmt.Errorf("failed to copy file permissions: %w", err)
}
// 수정 시간과 접근 시간 복사
if err := os.Chtimes(dstFile, srcInfo.ModTime(), srcInfo.ModTime()); err != nil {
return fmt.Errorf("failed to copy file timestamps: %w", err)
}
return nil
}