Rumah >pembangunan bahagian belakang >C++ >Apakah kaedah terbaik untuk menyalin fail dalam C dengan selamat dan cepat, dan apakah kelebihan dan kekurangan masing-masing?

Apakah kaedah terbaik untuk menyalin fail dalam C dengan selamat dan cepat, dan apakah kelebihan dan kekurangan masing-masing?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-25 03:29:20540semak imbas

What are the best methods for safely and quickly copying files in C  , and what are their respective advantages and disadvantages?

Menyalin Fail dengan Selamat dan Pantas dalam C

Gambaran Keseluruhan

Menyalin fail ialah tugas biasa dalam pengaturcaraan. Adalah penting untuk mendekati tugas ini dengan kewarasan dan kecekapan. Artikel ini meneroka pelbagai teknik untuk menyalin fail dalam C sambil membincangkan kebaikan dan keburukannya. Kami akan merangkumi fungsi C standard, fungsi POSIX dan penimbal strim C, antara lain.

Pendekatan ANSI C: fread() dan fwrite()

Pendekatan ini menggunakan fungsi perpustakaan standard C fread () dan fwrite() untuk membaca dan menulis data dalam blok. Walaupun ia menyediakan kawalan peringkat rendah, ia memerlukan pengurusan penimbal yang jelas dan boleh digunakan secara bertele-tele.

// ANSI-C-WAY
#include <stdio.h> // fopen(), fclose(), fread(), fwrite(), BUFSIZ
#include <cstdio> // size_t
using namespace std;

int main() {
    // Define buffer size (BUFSIZE default is 8192 bytes)
    const size_t BUFFER_SIZE = 4096;
    char buf[BUFFER_SIZE];
    size_t size;

    FILE* source = fopen("from.ogv", "rb");
    FILE* dest = fopen("to.ogv", "wb");

    while (size = fread(buf, 1, BUFFER_SIZE, source)) {
        fwrite(buf, 1, size, dest);
    }

    fclose(source);
    fclose(dest);

    return 0;
}

Pendekatan POSIX: read() dan write()

Pendekatan ini menggunakan POSIX read( ) dan fungsi write(), memberikan lebih kawalan ke atas operasi fail daripada pendekatan ANSI C. Ia menawarkan keupayaan untuk mengendalikan fail yang lebih besar dan mengendalikan ralat dengan lebih teliti.

// POSIX-WAY
#include <fcntl.h> // open()
#include <unistd.h> // read(), write(), close()
#include <stdio.h> // BUFSIZ
using namespace std;

int main() {
    // Define buffer size (BUFSIZE default is 8192 bytes)
    const size_t BUFFER_SIZE = 4096;
    char buf[BUFFER_SIZE];
    size_t size;

    int source = open("from.ogv", O_RDONLY, 0);
    int dest = open("to.ogv", O_WRONLY | O_CREAT | O_TRUNC, 0644);

    while ((size = read(source, buf, BUFFER_SIZE)) > 0) {
        write(dest, buf, size);
    }

    close(source);
    close(dest);

    return 0;
}

KISS-C -Streambuffer Approach: Stream Buffers

Pendekatan ini mengambil kesempatan daripada penampan strim C I/O. Ia ringkas dan mudah, menggunakan kaedah rdbuf() untuk menyalin keseluruhan fail, membiarkan masa jalan C mengendalikan I/O peringkat rendah.

// KISS-C++-Streambuffer-WAY
#include <iostream> // cout, cin
#include <fstream> // ifstream, ofstream
using namespace std;

int main() {
    ifstream source("from.ogv", ios::binary);
    ofstream dest("to.ogv", ios::binary);

    dest << source.rdbuf();

    source.close();
    dest.close();

    return 0;
}

PENDEKATAN COPY-ALGORITHM-C: copy() Algoritma

Algoritma C copy() boleh menyalin data dengan cekap dari satu fail ke fail yang lain. Pendekatan ini mendapat manfaat daripada iterator teguh STL, menghapuskan keperluan untuk mengendalikan pengurusan penimbal secara manual.

// COPY-ALGORITHM-C++-WAY
#include <iostream> // cout, cin
#include <fstream> // ifstream, ofstream
#include <ctime> // clock_t, clock()
#include <algorithm> // copy
#include <iterator> // istreambuf_iterator, ostreambuf_iterator
using namespace std;

int main() {
    ifstream source("from.ogv", ios::binary);
    ofstream dest("to.ogv", ios::binary);

    istreambuf_iterator<char> begin_source(source);
    istreambuf_iterator<char> end_source;
    ostreambuf_iterator<char> begin_dest(dest);
    copy(begin_source, end_source, begin_dest);

    source.close();
    dest.close();

    return 0;
}

Pendekatan OWN-BUFFER-C: Pengurusan Penampan Sendiri

Pendekatan ini memperuntukkan penimbalnya sendiri, menyediakan kawalan terperinci ke atas pengurusan memori dan saiz penimbal. Ia memerlukan deallocation memori yang teliti untuk mengelakkan kebocoran.

// OWN-BUFFER-C++-WAY
#include <iostream> // cout, cin
#include <fstream> // ifstream, ofstream
#include <ctime> // clock_t, clock()
using namespace std;

int main() {
    ifstream source("from.ogv", ios::binary);
    ofstream dest("to.ogv", ios::binary);

    // Determine file size and allocate buffer
    source.seekg(0, ios::end);
    ifstream::pos_type size = source.tellg();
    source.seekg(0, ios::beg);
    char* buffer = new char[size];

    // Copy file
    source.read(buffer, size);
    dest.write(buffer, size);

    // Cleanup
    delete[] buffer;
    source.close();
    dest.close();

    return 0;
}

Pendekatan LINUX: Fungsi sendfile()

Fungsi sendfile() khusus Linux mengambil kesempatan daripada pengoptimuman peringkat kernel dan pemindahan data langsung antara deskriptor fail. Pendekatan ini terkenal dengan kecekapannya, terutamanya pada pemindahan fail yang besar.

// LINUX-WAY
#include <iostream> // cout, cin
#include <sys/sendfile.h> // sendfile
#include <fcntl.h> // open
#include <unistd.h> // close
#include <sys/stat.h> // stat
#include <sys/types.h> // stat
#include <ctime> // clock_t, clock()
using namespace std;

int main() {
    int source = open("from.ogv", O_RDONLY, 0);
    int dest = open("to.ogv", O_WRONLY | O_CREAT | O_TRUNC, 0644);

    // Determine file size
    struct stat stat_source;
    fstat(source, &stat_source);

    // Copy file
    sendfile(dest, source, 0, stat_source.st_size);

    close(source);
    close(dest);

    return 0;
}

Perbandingan dan Kesimpulan

Pendekatan yang disediakan berbeza dari segi kerumitan, kecekapan dan kawalan. Berikut ialah ringkasan kekuatan dan batasan mereka:

Approach Pros Cons
ANSI C Low-level control, portable Verbose, buffer management required
POSIX More control than ANSI C, handles large files Still requires explicit buffer management
KISS-C -Streambuffer Concise, stream buffer manages I/O High-level, less control over buffering
COPY-ALGORITHM-C Efficient, STL iterators handle data transfer Requires caution with large files to avoid buffering issues
OWN-BUFFER-C Fine-grained control over buffer management Memory management must be handled carefully to avoid leaks
LINUX-sendfile() Fast, kernel-level optimization Linux-specific, requires elevated privileges

Memilih pendekatan terbaik bergantung pada keperluan khusus permohonan anda. Untuk fail kecil, kesederhanaan ifstream/ofstream mungkin memadai. Untuk fail besar atau senario di mana kecekapan adalah penting, sendfile() ialah pilihan yang bagus. Akhirnya, menguji dan menanda aras pendekatan berbeza disyorkan untuk menentukan penyelesaian optimum untuk kes penggunaan anda.

Atas ialah kandungan terperinci Apakah kaedah terbaik untuk menyalin fail dalam C dengan selamat dan cepat, dan apakah kelebihan dan kekurangan masing-masing?. 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