复制文件是编程中的常见任务。保持理智和高效地完成这项任务至关重要。本文探讨了用 C 语言复制文件的各种技术,同时讨论了它们的优缺点。我们将介绍标准 C 函数、POSIX 函数和 C 流缓冲区等。
此方法使用 C 标准库函数 fread () 和 fwrite() 以块的形式读写数据。虽然它提供低级控制,但它需要显式的缓冲区管理并且可能很冗长。
// 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; }
此方法利用 POSIX read( ) 和 write() 函数,比 ANSI C 方法提供更多对文件操作的控制。它提供了处理更大文件和更细致地处理错误的能力。
// 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; }
这种方法利用了 C I/O 流缓冲区。它简洁明了,利用 rdbuf() 方法复制整个文件,让 C 运行时处理低级 I/O。
// 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; }
C copy() 算法可以高效地将数据从一个文件复制到另一个文件。这种方法受益于 STL 强大的迭代器,无需手动处理缓冲区管理。
// 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; }
这种方法分配自己的缓冲区,提供对内存管理和缓冲区大小的细粒度控制。它需要仔细的内存释放以避免泄漏。
// 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; }
Linux 特定的 sendfile() 函数利用内核级优化和直接数据传输文件描述符之间。这种方法以其效率而闻名,特别是在大文件传输方面。
// 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; }
提供的方法在复杂性、效率和控制方面各不相同。以下是它们的优点和局限性的总结:
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 |
选择最佳方法取决于您应用程序的具体要求。对于小文件,ifstream/ofstream 的简单性可能就足够了。对于大文件或效率至关重要的场景,sendfile() 是一个不错的选择。最终,建议对不同的方法进行测试和基准测试,以确定适合您的用例的最佳解决方案。
以上是在 C 中安全快速地复制文件的最佳方法是什么,它们各自的优点和缺点是什么?的详细内容。更多信息请关注PHP中文网其他相关文章!