readdir(): перечитывание определенных файлов

У меня есть функция, задача которой состоит в том, чтобы переименовать все файлы в папке, однако она переименовывает определенные файлы: http://i.imgur.com/JjN8Qb2.png, такая же "ошибка" повторяется для каждого десятого числа. и далее. Что именно вызывает эту "ошибку"?

Два аргумента функции - это путь к папке и начальное значение, которое должен иметь первый файл.

int lookup(std::string path, int *start){
        int number_of_chars;
        std::string old_s, file_format, new_s;
        std::stringstream out;
        DIR *dir;
        struct dirent *ent;

        dir = opendir (path.c_str());
        if (dir != NULL) {
            // Read pass "." and ".."
            ent = readdir(dir);
            ent = readdir(dir);
            // Change name of all the files in the folder
            while((ent = readdir (dir)) != NULL){
                // Old string value
                old_s = path;
                old_s.append(ent->d_name);
                // Get the format of the image
                file_format = ent->d_name;
                number_of_chars = file_format.rfind(".");
                file_format.erase(0,number_of_chars);
                // New string value
                new_s = path;
                out << *start;
                new_s += out.str();
                new_s.append(file_format);
                std::cout << "Successfully changed name on " << ent->d_name << "\tto:\t" << *start << file_format << std::endl;
                // Switch name on the file from old string to new string
                rename(old_s.c_str(), new_s.c_str());

                out.str("");
                *start = *start+1;
            }
            closedir (dir);
        }
        // Couldn't open
        else{
            std::cerr << "\nCouldn't open folder, check admin privileges and/or provided file path\n" << std::endl;
            return 1;
        }

        return 0;
    }

2 ответа

Решение

Вы переименовываете файлы в ту же папку, в которой находились исходные файлы, что приводит к бесконечному циклу. Вы переименованы 04.png в 4.png но так как вы перебираете все файлы в папке, в какой-то момент вы собираетесь перебирать "новый" 4.png файл (в вашем smaple, на 40-й итерации) и переименуйте этот файл в 40.png и так далее...

Самый простой способ решить эту проблему с минимальными изменениями в существующем коде - это "переименовать" (переместить) файлы во временную папку с их новыми именами. Что-то вроде:

new_s = temp_path;
out << *start;
new_s += out.str();
new_s.append(file_format);
// Switch name on the file from old string to new string
rename(old_s.c_str(), new_s.c_str());

и когда вы закончите переименование всех файлов в path (вне while цикл), удалите папку и "переименуйте" (переместить) temp_path к `пути:

closedir (dir);
deletedir(path);
rename(temp_path, path);

`

Возможные проблемы, которые я вижу:

  • Переименование файлов приводит к их двойной подаче в ваш алгоритм.
  • Ваш алгоритм для вычисления нового имени файла неверен.

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

Другие вопросы по тегам