копирование содержимого файла в другой файл по n байтов за раз в c - PullRequest
0 голосов
/ 26 февраля 2020

Попытка скопировать содержимое файла в другой файл, копируя n байтов за раз в c. Я полагаю, что приведенный ниже код работает для копирования по одному байту за раз, но я не уверен, как заставить его работать для числа n байтов, пытался создать массив символов размером n и изменить функции чтения / записи на read(sourceFile , &c, n) и write(destFile , &c, n), но буфер не работает таким образом.

#include <fcntl.h>    
#include <unistd.h> 
#include <stdint.h>
#include <time.h>

void File_Copy(int sourceFile, int destFile, int n){
    char c;

    while(read(sourceFile , &c, 1) != 0){
        write(destFile , &c, 1);
    }


}

int main(){
    int fd, fd_destination;      
    fd = open("source_file.txt", O_RDONLY); //opening files to be read/created and written to
    fd_destination = open("destination_file.txt", O_RDWR | O_CREAT); 

    clock_t begin = clock(); //starting clock to time the copying function

    File_Copy(fd, fd_destination, 100); //copy function

    clock_t end = clock();
    double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; //timing display

return 0;
}

Ответы [ 3 ]

1 голос
/ 26 февраля 2020

как заставить его работать на n байтов

Просто прочитайте N байтов и скопируйте столько успешно прочитанных байтов.

#define N  4096 
void File_Copy(int sourceFile, int destFile, int n){
    char c[N];
    const size_t csize = sizeof(c)/sizeof(*c);
    while (1) {
        const ssize_t readed = read(sourceFile, c, csize);
        if (readed <= 0) {
            // nothing more to read
            break;
        }
        // copy to destination that many bytes we read
        const ssize_t written = write(destFile, c, readed);
        if (written != readed) {
            // we didn't transfer everything and destFile should be blocking
            // handle error
            abort();
        }
    }
}
0 голосов
/ 26 февраля 2020

Это моя версия, использующая lseek (не требуется l oop): она полагается на чтение и запись, всегда обрабатывая весь буфер, а не его часть (я не знаю, является ли это гарантировано).

void File_Copy(int sourceFile, int destFile)
{
    off_t s = lseek(sourceFile, 0, SEEK_END);
    lseek(sourceFile, 0, SEEK_SET);

    char* c = malloc(s);

    if (read(sourceFile, c, s) == s)
        write(destFile, c, s);

    free(c);
}

Следующий код не основывается на этом предположении и может также использоваться для файловых дескрипторов, не поддерживающих lseek .

void File_Copy(int sourceFile, int destFile, int n)
{
    char* c = malloc(n);
    while (1)
    {
        ssize_t readStatus = read(sourceFile, c, n);
        if (readStatus == -1)
        {
            printf("error, read returned -1, errno: %d\n", errno);
            return;
        }
        if (readStatus == 0)
            break; // EOF

        ssize_t bytesWritten = 0;
        while (bytesWritten != readStatus)
        {
            ssize_t writeStatus = write(destFile, c + bytesWritten, readStatus - bytesWritten);
            if (writeStatus == -1)
            {
                printf("error, write returned -1, errno is %d\n", errno);
                return;
            }
            bytesWritten += writeStatus;
            if (bytesWritten > readStatus) // should not be possible
            {
                printf("how did 'bytesWritten > readStatus' happen?");
                return;
            }
        }
    }
    free(c);
}

На моем система (P CIe SSD) Я получаю наилучшую производительность с буфером от 1 до 4 МБ (вы также можете использовать dd, чтобы найти этот размер). Большие буферы не имеют смысла. И вам нужны большие файлы (попробуйте 50 ГБ), чтобы увидеть эффект.

0 голосов
/ 26 февраля 2020

Вы хотите скопировать буфер размером n сразу:

void File_Copy(int sourceFile, int destFile, int n){
    char c[n];

    ssize_t st;
    while((st = read(sourceFile , c, n)) > 0){
        write(destFile , c, st);
    }
}

Обратите внимание, что необязательно n байты всегда копируются одновременно, возможно, их меньше. И вам также нужно проверить возвращаемое значение write() и обработать ситуацию, когда было записано меньше байтов, поскольку это соответствует вашим потребностям.

Один пример - это oop:

while (st > 0) {
    int w = write(destFile, c, st);
    if (w < 0) {
        perror("write");
        return;
    }
    st -= w;
}

Другая проблема: при создании файла назначения здесь

fd_destination = open("destination_file.txt", O_RDWR | O_CREAT);

вы не указываете третий параметр mode . Это приводит к случайному режиму, который может привести к сбою open() в следующий раз. Поэтому лучше добавьте действительный режим, например, такой:

fd_destination = open("destination_file.txt", O_RDWR | O_CREAT, 0644);

Это могло бы исказить результаты вашего теста.

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