Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mencapai Salinan Fail yang Teguh dan Cekap dalam Go Beyond os.Link()?

Bagaimana untuk Mencapai Salinan Fail yang Teguh dan Cekap dalam Go Beyond os.Link()?

Barbara Streisand
Barbara Streisandasal
2024-11-27 03:49:09940semak imbas

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

Salin Fail dalam Go: Melangkaui Asas

Kesederhanaan penyalinan fail dalam Go boleh mengelirukan. Walaupun fungsi os.Link() menyediakan kaedah yang dikatakan cekap, batasannya memerlukan pendekatan yang lebih komprehensif.

Link() Quirks

Os.Link() mencipta pautan keras antara dua fail, mengelakkan overhed pemindahan bait. Walau bagaimanapun, pendekatan ini mempunyai sekatan yang wujud. Sistem pengendalian yang berbeza mengenakan kekangan yang berbeza-beza pada pautan keras. Dalam senario tertentu, panggilan Pautan() mungkin gagal.

Salinan Fail Teguh

Untuk salinan yang mantap dan cekap, langkah berikut disyorkan:

  1. Semakan Prasalinan: Sahkan sama ada penyalinan boleh dilakukan (cth., kebenaran, direktori wujud).
  2. Semakan Fail Sama: Tentukan sama ada kedua-dua fail wujud dan sama menggunakan os.SameFile.
  3. Percubaan Pautan: Cuba buat pautan keras melalui os.Link.
  4. Byte-Copy Fallback: Jika pemautan gagal, salin byte-wise menggunakan io.Copy.

Dalam sesetengah kes, anda mungkin lebih suka fungsi berasingan untuk segerak (menyekat) dan tak segerak (tidak menyekat) penyalinan.

Contoh Dioptimumkan

Coretan kod berikut melaksanakan fungsi salinan fail komprehensif, CopyFile(), yang menggabungkan langkah-langkah yang disyorkan:

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()
}

Fungsi ini menggabungkan kecekapan, keteguhan dan pengendalian untuk pelbagai kes tepi.

Atas ialah kandungan terperinci Bagaimana untuk Mencapai Salinan Fail yang Teguh dan Cekap dalam Go Beyond os.Link()?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn