2. 파일 복사하기
페이지 정보
작성자 관리자 댓글 0건 조회 1,469회 작성일 21-07-19 17:10본문
2. 파일 복사하기
기존 파일을 복제하려는 경우 os.Link(srcName, dstName)를 사용할 수 있습니다. 이렇게하면 응용 프로그램에서 바이트를 이동하지 않아도되며 디스크 공간이 절약됩니다. 큰 파일의 경우 시간과 공간을 크게 절약합니다.
그러나 운영 체제마다 하드 링크 작동 방식에 대한 제한이 다릅니다. 응용 프로그램 및 대상 시스템 구성에 따라 Link() 호출이 모든 경우에 작동하지 않을 수 있습니다.
단일의 강력하고 효율적인 단일 복사 기능을 원하면 Copy()를 다음과 같이 업데이트하십시오.
최소한 일부 형식의 복사 (성공한 액세스 권한, 디렉토리 등)가 있는지 확인하십시오.
두 파일이 이미 존재하고 동일한 파일인지 확인하십시오.
os.SameFile, 같은 경우 성공을 반환
링크 시도, 성공하면 반환
바이트를 복사하십시오 (모두 효율적인 수단이 실패했습니다).
최적화는 이동 루틴에서 바이트를 복사하여 호출자가 바이트 복사를 차단하지 않도록하는 것입니다. 그렇게하면 호출자가 성공 / 오류 사례를 올바르게 처리하기 위해 추가 복잡성을 부과합니다.
둘 다 원하는 경우 차단 복사본의 경우 CopyFile(src, dst string) (error)와 비동기 사례의 경우 신호 채널을 호출자에게 다시 전달하는 CopyFileAsync(src, dst string) (chan c, error)의 두 가지 복사 기능이 있습니다.
package main
import (
"fmt"
"io"
"os"
)
// CopyFile copies a file from src to dst. If src and dst files exist, and are
// the same, then return success. Otherise, attempt to create a hard link
// between the two files. If that fail, copy the file contents from src to dst.
func CopyFile(src, dst string) (err error) {
sfi, err := os.Stat(src)
if err != nil {
return
}
if !sfi.Mode().IsRegular() {
// cannot copy non-regular files (e.g., directories,
// symlinks, devices, etc.)
return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String())
}
dfi, err := os.Stat(dst)
if err != nil {
if !os.IsNotExist(err) {
return
}
} else {
if !(dfi.Mode().IsRegular()) {
return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String())
}
if os.SameFile(sfi, dfi) {
return
}
}
if err = os.Link(src, dst); err == nil {
return
}
err = copyFileContents(src, dst)
return
}
// copyFileContents copies the contents of the file named src to the file named
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all it's contents will be replaced by the contents
// of the source file.
func copyFileContents(src, dst string) (err error) {
in, err := os.Open(src)
if err != nil {
return
}
defer in.Close()
out, err := os.Create(dst)
if err != nil {
return
}
defer func() {
cerr := out.Close()
if err == nil {
err = cerr
}
}()
if _, err = io.Copy(out, in); err != nil {
return
}
err = out.Sync()
return
}
func main() {
fmt.Printf("Copying %s to %s\n", os.Args[1], os.Args[2])
err := CopyFile(os.Args[1], os.Args[2])
if err != nil {
fmt.Printf("CopyFile failed %q\n", err)
} else {
fmt.Printf("CopyFile succeeded\n")
}
}
댓글목록
등록된 댓글이 없습니다.