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 }