Скопируйте данные из файла X в файл Y программы на C - PullRequest
0 голосов
/ 18 марта 2019

Я попытался написать базовую программу на C, которая копирует данные из файла в другой с заданным исходным путем, целевым путем и размером буфера в качестве входных данных.Моя проблема заключается в том, что целевой файл заполнен мусором или чем-то еще, потому что он намного больше исходного (увеличивается в зависимости от размера буфера) и не может быть открыт.Как мне прочитать и записать только байты в источнике?я работаю в Linux, и это на самом деле копирование часть:

char buffer[buffer_size];

int readable=1;
int writeable;
while(readable != 0){
    readable = read(sourcef, buffer, buffer_size);
    if(readable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not read.");
    }
    writeable = write(destf, buffer, buffer_size);
    if(writeable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not write.");
    }
}

Ответы [ 3 ]

3 голосов
/ 18 марта 2019
writeable = write(destf, buffer, buffer_size);

должно быть

writeable = write(destf, buffer, readable);

В настоящее время вы пишете не количество прочитанных символов, а весь буфер, поэтому выходной файл слишком велик

Вы также неправильно управляете концом входного файла

Возвращаемое значение read :

  • В случае успехаколичество прочитанных байтов возвращается (ноль указывает на конец файла)

  • При ошибке возвращается -1

Предложение:

/* you already check input and output file was open with success */

char buffer[buffer_size];

for(;;){
  ssize_t readable = read(sourcef, buffer, buffer_size);

  if(readable <= 0){
    close(sourcef);
    close(destf);
    if (readable != 0)
      /* not EOF */
      exit_with_usage("Could not read.");
    /* EOF */
    break;
  }

  if (write(destf, buffer, n) != n) {
    close(sourcef);
    close(destf);
    exit_with_usage("Could not write.");
  }
}

Полагаю, exit_with_usage вызывает exit(), поэтому не возвращает

Примечание в теории запись может писать меньше ожидаемого количества символов, не будучиошибка, и запись должна выполняться в цикле, но в этом случае бесполезно управлять этим

2 голосов
/ 18 марта 2019

Функция чтения возвращает количество байтов, которые были прочитаны в буфер (который имеет размер_букера). Не всегда фактические считанные байты имеют то же значение, что и размер буфера (рассмотрим сценарий, если в исходном файле осталось недостаточно байтов, чтобы полностью заполнить буфер). Поэтому вы должны записывать в целевой файл не размер_буфера (третий аргумент функции записи), а количество прочитанных вами байтов - это читаемая переменная в вашем коде

0 голосов
/ 18 марта 2019

Вы должны выйти, когда readable возвращает ошибку. Поэтому

while(readable != 0){

должно быть

while(readable != -1){

, чтобы цикл мог завершиться при исчерпании файла чтения.

В настоящее время вы видите, что после прочтения всего файла чтения вызов read завершается неудачно, но write вызывается повторно, так как выполнение не имеет пути выхода для сбоя при чтении.Также write должен писать только количество прочитанных байтов.Таким образом, код будет выглядеть так:

char buffer[buffer_size];

int readable=1;
int writeable;
while(readable != -1){
    readable = read(sourcef, buffer, buffer_size);
    if(readable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not read.");
    }
    writeable = write(destf, buffer, readable);
    if(writeable == -1){
        close(sourcef);
        close(destf);
        exit_with_usage("Could not write.");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...