Как скопировать или записать весь файл в другой файл, используя 'BUFSIZ' в программе на C? - PullRequest
0 голосов
/ 06 июля 2019

Попытка прочитать файл и записать в другой новый файл, используя BUFSIZ C. Но цикл чтения идет бесконечно. Где проблема и как ее исправить.

[cpy.c]
// Copy from file 1 to file 2

#include <stdio.h>
#include <stdlib.h> // For 'exit'
#include <stdarg.h> // For va_args

#include "unistd.h" // For 'open'  (for Windows Only)
#include <fcntl.h>  // For 'O_RDONLY'

#define PERMS 0666

void error(char *, ...);

long getFileSize(char *);

int main(int argc, char *argv[])
{
    ssize_t n;
    int f1, f2;
    char buf[BUFSIZ];

    long writtenBytes = 0;
    float toMb = 1024 * 1024;
    float percent;

    if (argc < 3) {
        error("Usage: cpy <from.ext> <to.ext>");
    }

    // Opening source file.
    if ((f1 = open(argv[1], O_RDONLY, 0)) == -1)
        error("Unable to read a %s file.", argv[1]);

    long fileSize = getFileSize(argv[1]); // in Bytes
    float fileSizeMb = fileSize / toMb;
    printf("Source file (Size: %.2f Mb): %s\n", fileSizeMb, argv[1]);

    // Create a Destination file
    if ((f2 = creat(argv[2], PERMS)) == -1)
        error("Unable to create a destination file (%s).", argv[2]);

    // Read a source file.
    while ((n = read(f1, buf, BUFSIZ)) != -1) // > 0 // **TO FIX #1** 
        if (write(f2, buf, n) != n)
            error("While writing data to (%s) file! Please try again.", argv[2]);
        else {
            //printf("\r%d Bytes are readed now.", n);
            writtenBytes += BUFSIZ; //(long) n;  // **TO FIX #2** 

            percent = (float) writtenBytes / fileSize;
            printf("\r%.2f%% (%.2f / %.2f Mb) is completed", percent, writtenBytes/(toMb*100.0), fileSizeMb);
            //fflush(stdout);
        }

    printf("\nFile (%s) is copied.", argv[2]);
    return 0;
}

// Get The size of the file.
long getFileSize(char *filepath)
{
    FILE *fh = fopen(filepath, "r");

    if (fh == NULL) {
        error("FILESIZE: Unable to open a \"%s\" file.\n", filepath);
        return 0;
    }

    // Go to end of the file.
    fseek(fh, 0, SEEK_END);
    long filesize = ftell(fh);
    // Set back seek to beginning of the file, for next time read.
    fseek(fh, 0, SEEK_SET);
    return filesize;
}

// Print an Error msg and die
void error(char *fmt, ...)
{
    va_list args;

    va_start(args, fmt);
    fprintf(stderr, "Error: ");
    vfprintf(stderr, fmt, args);
    fprintf(stderr, "\n");
    va_end(args);

    exit(1);
}

Цель состоит в том, чтобы прочитать, записать его в новый файл и показать «Процент» завершения, а также байты, которые уже записаны в данный момент.

Как и предполагалось, исправляемая строка помечается как "** TO FIX ## '** внутри кода.

  • Код "TO FIX # 1" - при использовании '> 0' на самом деле ничего не пишется.
  • Код "К ИСПРАВЛЕНИЮ № 2" - я думаю, это должно быть 'n' вместо 'BUFSIZ', чтобы получить точные байты, должны быть записаны в конце завершение.

И, наконец, «90 МБ» файла всегда записывается только в «11 КБ», после «Ctrl + C».

Компиляция: gcc -o bin/cpy cpy.c -Wall

Выполнить: cpy от .mp4 до .mp4

Env: кодовые блоки 17.12, Windows 10 64Bit

Заранее спасибо.

1 Ответ

0 голосов
/ 07 июля 2019

Когда read (2) достигает конца файла, он возвращает 0 , а не -1. ​​

Ваш код достигает конца файла, и с этого момента read возвращает0, но вы остановитесь только на -1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...