Go Beyond os.Link()에서 강력하고 효율적인 파일 복사를 달성하는 방법은 무엇입니까?

Barbara Streisand
풀어 주다: 2024-11-27 03:49:09
원래의
943명이 탐색했습니다.

How to Achieve Robust and Efficient File Copy in Go Beyond os.Link()?

Go의 파일 복사: 기본을 넘어서

Go의 파일 복사 단순성은 오해를 불러일으킬 수 있습니다. os.Link() 함수는 효율적인 방법을 제공한다고 알려져 있지만 그 제한으로 인해 보다 포괄적인 접근 방식이 필요합니다.

Link() Quirks

Os.Link()는 다음을 생성합니다. 두 파일 간의 하드 링크로 바이트 전송의 오버헤드를 방지합니다. 그러나 이 접근 방식에는 본질적인 제한 사항이 있습니다. 운영 체제에 따라 하드 링크에 다양한 제약이 적용됩니다. 특정 시나리오에서는 Link() 호출이 실패할 수 있습니다.

강력한 파일 복사

강력하고 효율적인 복사를 위해 다음 단계를 권장합니다.

  1. 복사 전 확인: 복사가 가능한지 확인합니다(예: 권한, 디렉터리 존재).
  2. 동일 파일 확인: os.SameFile을 사용하여 두 파일이 모두 존재하고 동일한지 확인합니다.
  3. 링크 시도: 설정을 시도합니다. os.Link를 통한 하드 링크.
  4. 바이트 복사 대체: 연결이 실패하면 io.Copy를 사용하여 바이트 단위로 복사하세요.

경우에 따라 동기(차단) 및 비동기(비차단) 복사에 대해 별도의 기능을 선호할 수도 있습니다.

최적화된 예

다음 코드 스니펫은 권장 단계를 통합하는 포괄적인 파일 복사 기능인 CopyFile()을 구현합니다.

package main

import (
    "fmt"
    "io"
    "os"
)

// CopyFile implements a robust and efficient file copy.
func CopyFile(src, dst string) (err error) {
    sfi, err := os.Stat(src)
    if err != nil {
        return err
    }
    if !sfi.Mode().IsRegular() {
        return fmt.Errorf("CopyFile: Non-regular source file %s (%q)", sfi.Name(), sfi.Mode())
    }
    dfi, err := os.Stat(dst)
    if err != nil {
        if os.IsNotExist(err) {
            return nil // Destination file doesn't exist, so no copying required.
        }
        return err
    }
    if !(dfi.Mode().IsRegular()) {
        return fmt.Errorf("CopyFile: Non-regular destination file %s (%q)", dfi.Name(), dfi.Mode())
    }
    if os.SameFile(sfi, dfi) {
        return nil // Files are identical, so no copying required.
    }
    if err = os.Link(src, dst); err == nil {
        return nil // Hard link succeeded.
    }
    err = copyFileContents(src, dst)
    return err
}

// copyFileContents performs a byte-wise copy of the source file to the destination file.
func copyFileContents(src, dst string) error {
    in, err := os.Open(src)
    if err != nil {
        return err
    }
    defer in.Close()
    out, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer func() {
        if err == nil {
            err = out.Close()
        }
    }()
    if _, err = io.Copy(out, in); err != nil {
        return err
    }
    return out.Sync()
}
로그인 후 복사

이 기능은 효율성, 견고성 및 다양한 경우에 대한 처리를 결합합니다.

위 내용은 Go Beyond os.Link()에서 강력하고 효율적인 파일 복사를 달성하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿