ホームページ > バックエンド開発 > C++ > C でファイルを安全かつ迅速にコピーするための最良の方法は何ですか?また、それぞれの長所と短所は何ですか?

C でファイルを安全かつ迅速にコピーするための最良の方法は何ですか?また、それぞれの長所と短所は何ですか?

Mary-Kate Olsen
リリース: 2024-12-25 03:29:20
オリジナル
575 人が閲覧しました

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 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート