Copy text and binary files with one function?

I have two functions. One of these copies text files that use the modes "r"and "w"to read and write, and copy the binaries that use modes "rb"and "wb.

But if I had to use these functions, I must first determine if the file I want to duplicate is a text or binary file. I want a solution that allows me to copy a file successfully, without knowing earlier about the nature of the file. The only function that deals with this issue. Any ideas?

PS: I noticed that the copy ctrl + cis faster than my function, so tips on improving the speed of the function are also welcome.

#include <stdio.h>

void copyfile_txt(const char *inputfile, const char *outputfile);
void copyfile_bin(const char *inputfile, const char *outputfile);

int main(void)
{
    copyfile_txt("file_input.txt", "file_output.txt");
    copyfile_bin("ubuntu-14.04.3-desktop-amd64.iso", "Ubuntu.iso");
    return 0;
}

long GetFileSize(FILE *fp)
{
    fseek(fp, 0L, SEEK_END);
    long sz = ftell(fp);
    fseek(fp, 0L, SEEK_SET);
    return sz;
}
void copyfile_txt(const char *inputfile, const char *outputfile)
{
    static FILE *fp_I;
    static FILE *fp_O;

    fp_I = fopen(inputfile, "r");
    if (!fp_I) {
        perror(inputfile);
        return;
    }

    fp_O = fopen(outputfile, "w");
    if (!fp_O) {
        fclose(fp_I);
        perror(outputfile);
        return;
    }

    static int c;
    while ((c = getc(fp_I)) != EOF) {
        putc(c, fp_O);
    }
    fclose(fp_I);
    fclose(fp_O);
}
void copyfile_bin(const char *inputfile, const char *outputfile)
{
    static FILE *fp_I;
    static FILE *fp_O;

    fp_I = fopen(inputfile, "rb");
    if (!fp_I) {
        perror(inputfile);
        return;
    }

    fp_O = fopen(outputfile, "wb");
    if (!fp_O) {
        fclose(fp_I);
        perror(outputfile);
        return;
    }

    static int c;
    static long n;
    static long sz;

    n = 0;
    sz = GetFileSize(fp_I);

    while (n++ < sz) {
        c = getc(fp_I);
        putc(c, fp_O);
    }

    fclose(fp_I);
    fclose(fp_O);
}
+4
1

, . , .

, , :

  • , , EOF LONG_MAX.

  • : static .

  • .

:

int copyfile_bin(const char *inputfile, const char *outputfile) {
    FILE *fp_I;
    FILE *fp_O;

    fp_I = fopen(inputfile, "rb");
    if (!fp_I) {
        perror(inputfile);
        return -1;
    }

    fp_O = fopen(outputfile, "wb");
    if (!fp_O) {
        fclose(fp_I);
        perror(outputfile);
        return -1;
    }

    int c;
    while ((c = getc(fp_I)) != EOF) {
        putc(c, fp_O);
    }

    fclose(fp_I);
    if (fclose(fp_O) != 0) {
        perror(outputfile);
        return -1;
    }
    return 0;
}

, setvbuf() fread() fwrite() .

:

    size_t nr, size = 1024 * 1024;
    void *buffer = malloc(size);
    if (buffer != NULL) {
        while ((nr = fread(buffer, 1, size, fp_I)) > 0) {
            if (fwrite(buffer, 1, nr, fp_O) != nr) {
                fprintf(stderr, "write error: ");
                perror(outputfile);
                free(buffer);
                fclose(fp_I);
                fclose(fp_O);
                return -1;
            }
        }
        if (ferror(fp_I)) {
            fprintf(stderr, "read error: ");
            perror(inputfile);
            free(buffer);
            fclose(fp_I);
            fclose(fp_O);
            return -1;
        }
        free(buffer);
    } else {
        /* use the regular getc/putc loop */
        int c;
        while ((c = getc(fp_I)) != EOF) {
            putc(c, fp_O);
        }
    }
+4

Source: https://habr.com/ru/post/1652757/


All Articles