Rumah >pembangunan bahagian belakang >C++ >Apakah kaedah terbaik untuk menyalin fail dalam C dengan selamat dan cepat, dan apakah kelebihan dan kekurangan masing-masing?
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 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 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; }
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; }
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 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; }
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; }
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!