首页 >后端开发 >C++ >在 C 中安全快速地复制文件的最佳方法是什么,它们各自的优点和缺点是什么?

在 C 中安全快速地复制文件的最佳方法是什么,它们各自的优点和缺点是什么?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-12-25 03:29:20540浏览

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

在 C 语言中安全快速地复制文件

概述

复制文件是编程中的常见任务。保持理智和高效地完成这项任务至关重要。本文探讨了用 C 语言复制文件的各种技术,同时讨论了它们的优缺点。我们将介绍标准 C 函数、POSIX 函数和 C 流缓冲区等。

ANSI C 方法:fread() 和 fwrite()

此方法使用 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()

此方法利用 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;
}

KISS-C -Streambuffer 方法:流缓冲区

这种方法利用了 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;
}

COPY-ALGORITHM-C 方法:copy() 算法

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 方法:自己的缓冲区管理

这种方法分配自己的缓冲区,提供对内存管理和缓冲区大小的细粒度控制。它需要仔细的内存释放以避免泄漏。

// 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 特定的 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn