Переименование файлов в каталоге

144
15 сентября 2019, 18:40

Подскажите почему не происходит замена, компилирует, но замена не происходит.

#include <stdio.h>
#include <iostream>
#include <dirent.h>
#include <sstream>

int main() 
{
std::string directory = "katalog";
int i = 1;
std::string s, oldname, newname;
const char * OLDNAME, * NEWNAME;
DIR *dir;
struct dirent *entry;
const char * DIRECTORY;
DIRECTORY = directory.c_str();
dir = opendir (DIRECTORY);
while ((entry=readdir(dir))!=NULL)
{
    std::stringstream out;
    out << i;
    s = out.str();
    oldname = (std::string(DIRECTORY)+entry->d_name).c_str();
    newname = (std::string(DIRECTORY)+"" + s).c_str();
    OLDNAME = oldname.c_str();
    NEWNAME = newname.c_str();
    rename(OLDNAME, NEWNAME);
    i++;
}   
closedir(dir);
}
Answer 1

Вот программа, которая переименовывает (новое имя файла, совпадает с его "порядковым номером") файлы в каталоге.

#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
int main () 
{
  const char *directory = "katalog";
  char oldname[PATH_MAX + 1],
    newname[PATH_MAX + 1];
  int pos = sprintf(oldname, "%s/", directory);
  strcpy(newname, oldname);
  char *fromfile = oldname + pos,
    *tofile = newname + pos;
  DIR *dir = opendir(directory);
  if (!dir)
    exit((perror(directory), 1));
  struct dirent *entry;
  int i = 0;
  while ((entry = readdir(dir))) {
    if (strcmp(entry->d_name, ".") == 0 ||
        strcmp(entry->d_name, "..") == 0)
      continue;
    strcpy(fromfile, entry->d_name);
    sprintf(tofile, "%d", ++i);
    if (rename(oldname, newname))
      fprintf(stderr, "Can't rename [%s] to [%s] (%m)\n",
              oldname, newname);
  }
  closedir(dir);
}

Тщательно не исследовал, но с каталогом в котором 500 файлов она работает правильно, а вот если в каталоге 50000 файлов, то в результате в нем остается те же 50000 файлов, но присутствуют файлы с именами 60000, 69999 и т.п. (более 50000), которых быть не должно. Такой результат означает лишь то, что в ходе переименований имена некоторых, уже переименованных файлов, читаются снова.

Т.о. корректная программа для подобного массового переименования должна сначала прочесть все имена в каталоге (в память или временный файл), выполнить closedir() (в принципе, это не обязательно, главное не читать содержимое DIR *dir снова) и затем, перебирая запомненные имена в цикле, переименовать их.

READ ALSO
Разработка и отладка для arm-linux из Visual Studio

Разработка и отладка для arm-linux из Visual Studio

может быть кто то сталкивался с подобным ? Есть эмулятор Raspberry Pi emulation for Windows https://sourceforgenet/projects/rpiqemuwindows/ Линукс запускается там Есть реальная...

147
Что будет эффективнее?

Что будет эффективнее?

Имеем мы 8 функций:

145
C style cast в С и С++

C style cast в С и С++

C cast в С++ имеет следующую последовательность cast'ов:

125