@Alertoso

Почему при копировании файлов получаются битые файлы?

Само задание звучит так:
Отсортировать в заданном каталоге (аргумент 1 командной строки) и во всех его подкаталогах файлы по следующим критериям (аргумент 2 командной строки, задаётся в виде целого числа):1 – по размеру файла, 2 – по имени файла. Записать без сохранения структуры каталогов отсортированные файлы общим списком, в новый каталог (аргумент 3 командной строки). В связи с индексированием файлов в каталогах для файловых систем ext 2,3,4 перед запуском программы необходимо временно отключить опцию индексирования файловой системы следующим образом:
sudo tune2fs –O ^dir_index /dev/sdaXY
Проверить результат, используя, ls -l –f.
Программа работает, но файлы получаются скопированные битые(скриншот приложил ниже), проверил индексирование, дело не в нём, в чём может быть проблема?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>

/*
 * Отсортировать в заданном каталоге (аргумент 1 командной строки) и во всех его подкаталогах файлы по следующим критериям
 * (аргумент 2 командной строки, задаётся в виде целого числа): 1 – по размеру файла, 2 – по имени файла.
 * Записать без сохранения структуры каталогов отсортированные файлы общим списком, в новый каталог (аргумент 3 командной строки).
 * В связи с индексированием файлов в каталогах для файловых систем ext 2,3,4 перед запуском программы необходимо временно отключить
 * опцию индексирования файловой системы следующим образом: sudo tune2fs –O ^dir_index /dev/sdaXY
 */

// Структура файла: путь, название, размер
typedef struct {
    char path[PATH_MAX];
    char name[FILENAME_MAX];
    int  size;
} file_t;

// Список файлов
file_t *f_list;
int f_list_len = 0;

int (*cmpFunc)(file_t file1, file_t file2);

// Сравнение файлов по размеру
int cmpSize(file_t file1, file_t file2) {
    return ((file1.size - file2.size) < 0);
}

// Сравнение файлов по имени
int cmpName(file_t file1, file_t file2) {
    return (strcmp(file1.name, file2.name) > 0);
}

// Для перехода к подкаталогу
char* addSlash(char* path) {
    if (path[strlen(path) - 1] != '/')
        strcat(path, "/");
    return path;
}

// Чтение данных из директории и запись данных в список для хранения
int getFiles(char *dir_name) {
    DIR *directory;

    if ((directory = opendir(dir_name)) == NULL) {
        fprintf(stderr, "Error when trying to open the directory: %s\n", dir_name);
        return 0;
    }

    struct dirent *dir_item;
    while((dir_item = readdir(directory)) != NULL) {
        char next_item[PATH_MAX];
        strcpy(next_item, dir_name);
        strcat(next_item, dir_item->d_name);
        if(strcmp(".", dir_item->d_name) == 0 || strcmp("..", dir_item->d_name) == 0)
            continue;
        struct stat statbuf;
        lstat(next_item, &statbuf);
        if(S_ISDIR(statbuf.st_mode)) {
            getFiles(addSlash(next_item));
        } else if(S_ISREG(statbuf.st_mode)) {
            file_t file_tmp;
            strcpy(file_tmp.name, dir_item->d_name);
            strcpy(file_tmp.path, next_item);
            file_tmp.size = (int) statbuf.st_size;
            f_list = realloc(f_list, (++f_list_len)*sizeof(file_t));
            f_list[f_list_len - 1] = file_tmp;
        }
    }

    if (closedir(directory)) {
        fprintf(stderr, "Error when trying to close the directory: %s\n", dir_name);
        return 0;
    }
}

// Сортировка файлов по размеру или имени
void fListSort(int sortOption) {
    if (sortOption == 1)
        cmpFunc = cmpSize;
    else
        cmpFunc = cmpName;

    int i, j;
    for (i = 0; i < f_list_len; i++) {
        for (j = 0; j < f_list_len - i - 1; j++) {
            if (cmpFunc(f_list[j], f_list[j+1])) {
                file_t file_tmp = f_list[j];
                f_list[j] = f_list[j+1];
                f_list[j+1] = file_tmp;
            }
        }
    }
}

// Запись файлов в новый каталог 
int writeFiles(char *dir_name) {
    DIR *directory;

    if ((directory = opendir(dir_name)) == NULL) {
        fprintf(stderr, "Error when trying to open the directory: %s\n", dir_name);
        return 0;
    }

    int i, j;
    for(i = 0; i < f_list_len; i++) {
        j = i;
        while (j++ < f_list_len && !strcmp(f_list[i].name, f_list[j].name)) {
            char add_index[5];
            sprintf(add_index," (%d)", j-i);
            strcat(f_list[j].name, add_index);
        }

        char dist_file[PATH_MAX];
        strcpy(dist_file, dir_name);
        strcat(dist_file, f_list[i].name);

        if (symlink(f_list[i].path, dist_file) == -1) {
            fprintf(stderr, "%s: File exists\n", dist_file);
        }
    }

    if (closedir(directory)) {
        fprintf(stderr, "Error when trying to close the directory: %s\n", dir_name);
        return 0;
    }
}

int main(int argc, char *argv[]) {
    if (argc != 4) {
        fprintf(stderr, "Wrong number of arguments! You should enter 3 parameters:\n");
        fprintf(stderr, "First argument - source directory\n");
        fprintf(stderr, "Second argument - sort option\n");
        fprintf(stderr, "Third argument - destination directory\n");
        return 0;
    }

    char sortOption;
    sortOption = atoi(argv[2]);
    if (sortOption != 1 && sortOption != 2) {
        fprintf(stderr,"Wrong sort option! Must be: 1 or 2\n");
        return 0;
    }

    char dirSrc[PATH_MAX];
    strcpy(dirSrc, argv[1]);
    getFiles(addSlash(dirSrc));

    fListSort(sortOption);

    char dirDest[PATH_MAX];
    realpath(argv[3], dirDest);
    writeFiles(addSlash(dirDest));

    return 0;
}

622b4bc8758dd254404869.jpeg
  • Вопрос задан
  • 287 просмотров
Решения вопроса 1
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
Аккуратно выведите куда-нибудь параметры, которые вы передаете в функцию создания symlink.

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы