HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppCritical

Copy a file in a sane, safe and efficient way

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
efficientandcopyfilewaysafesane

Problem

I search for a good way to copy a file (binary or text). I've written several samples, everyone works. But I want hear the opinion of seasoned programmers.

I missing good examples and search a way which works with C++.

ANSI-C-WAY

#include 
#include     // fopen, fclose, fread, fwrite, BUFSIZ
#include 
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    // BUFSIZE default is 8192 bytes
    // BUFSIZE of 1 means one chareter at time
    // good values should fit to blocksize, like 1024 or 4096
    // higher values reduce number of system calls
    // size_t BUFFER_SIZE = 4096;

    char buf[BUFSIZ];
    size_t size;

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

    // clean and more secure
    // feof(FILE* stream) returns non-zero if the end of file indicator for stream is set

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

    fclose(source);
    fclose(dest);

    end = clock();

    cout (end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}


POSIX-WAY (K&R use this in "The C programming language", more low-level)

#include 
#include    // open
#include   // read, write, close
#include     // BUFSIZ
#include 
using namespace std;

int main() {
    clock_t start, end;
    start = clock();

    // BUFSIZE defaults to 8192
    // BUFSIZE of 1 means one chareter at time
    // good values should fit to blocksize, like 1024 or 4096
    // higher values reduce number of system calls
    // size_t BUFFER_SIZE = 4096;

    char buf[BUFSIZ];
    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, BUFSIZ)) > 0) {
        write(dest, buf, size);
    }

    close(source);
    close(dest);

    end = clock();

    cout (end - start) / CLOCKS_PER_SEC << "\n";

    return 0;
}


KISS-C++-Streambuffer-WAY

```
#include
#in

Solution

Copy a file in a sane way:

#include 

int main()
{
    std::ifstream  src("from.ogv", std::ios::binary);
    std::ofstream  dst("to.ogv",   std::ios::binary);

    dst << src.rdbuf();
}


This is so simple and intuitive to read it is worth the extra cost. If we were doing it a lot, better to fall back on OS calls to the file system. I am sure boost has a copy file method in its filesystem class.

There is a C method for interacting with the file system:

#include 

int
copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags);

Code Snippets

#include <fstream>

int main()
{
    std::ifstream  src("from.ogv", std::ios::binary);
    std::ofstream  dst("to.ogv",   std::ios::binary);

    dst << src.rdbuf();
}
#include <copyfile.h>

int
copyfile(const char *from, const char *to, copyfile_state_t state, copyfile_flags_t flags);

Context

Stack Overflow Q#10195343, score: 302

Revisions (0)

No revisions yet.