Рекурсивный CreateDirectory - PullRequest
       16

Рекурсивный CreateDirectory

2 голосов
/ 05 октября 2009

Я нашел множество примеров созданияDirectory рекурсивно, но не тот, который искал.

вот спецификация

С учетом ввода

  1. \\ сервер \ папка \ аа \ бб \ сс
  2. C: \ аа \ бб \ куб.см

ИСПОЛЬЗОВАНИЕ вспомогательного API

 CreateDirectory (char * path)
 returns true, if successful
 else
 FALSE

Условие: не должно быть никакого анализа, чтобы различать, является ли путь Локальным или общим сервером.

Написать подпрограмму на C или C ++

Ответы [ 8 ]

6 голосов
/ 05 октября 2012

Я думаю, что это намного проще ... вот версия, которая работает в каждой версии Windows:

unsigned int pos = 0;
do
{
    pos = path.find_first_of("\\/", pos + 1);
    CreateDirectory(path.substr(0, pos).c_str(), NULL);
} while (pos != std::string::npos);

Unicode:

pos = path.find_first_of(L"\\/", pos + 1);

С уважением,

2 голосов
/ 04 сентября 2011

Это может быть именно то, что вы хотите. Он не пытается выполнить синтаксический анализ, чтобы определить, является ли путь локальным или общим сервером.

bool TryCreateDirectory(char *path){
    char *p;
    bool b;

    if(
        !(b=CreateDirectory(path))
        &&
        !(b=NULL==(p=strrchr(path, '\\')))
        ){
        size_t i;

        (p=strncpy((char *)malloc(1+i), path, i=p-path))[i]='\0';
        b=TryCreateDirectory(p);
        free(p);
        b=b?CreateDirectory(path):false;
    }

    return b;
}

Алгоритм довольно прост, просто рекурсивно передайте строку каталога более высокого уровня, в то время как создание текущего уровня каталога завершится неудачей, пока не произойдет один успех или не будет более высокого уровня. Когда внутренний вызов возвращается с успехом, создайте текущий. Этот метод не выполняет синтаксический анализ для определения локального или самого сервера, он соответствует CreateDirectory. В WINAPI CreateDirectory никогда не позволяет вам создавать «c:» или «\», когда путь достигает этого уровня, метод вскоре переходит к вызову self с помощью path = «», и это тоже не удается. Именно поэтому Microsoft определяет правило именования общего доступа к файлам таким образом, чтобы обеспечить совместимость правила пути DOS и упростить кодирование.

1 голос
/ 05 октября 2009

Как насчет использования MakeSureDirectoryPathExists ()?

1 голос
/ 05 октября 2009

Абсолютно хакерский и небезопасный, и ничего, что вы на самом деле хотели бы сделать в рабочем коде, но ...

Предупреждение: здесь будет код, набранный в браузере:

int createDirectory(const char * path) {
  char * buffer = malloc((strlen(path) + 10) * sizeof(char));
  sprintf(buffer, "mkdir -p %s", path);
  int result = system(buffer);
  free(buffer);
  return result;
}
0 голосов
/ 14 апреля 2016
void createFolders(const std::string &s, char delim) {
std::stringstream ss(s);
std::string item;
char combinedName[50]={'\0'};
while (std::getline(ss, item, delim)) { 
  sprintf(combinedName,"%s%s%c",combinedName,item.c_str(),delim);          
  cout<<combinedName<<endl;
  struct stat st = {0};
  if (stat(combinedName,&st)==-1)
   { 
            #if REDHAT
                     mkdir(combinedName,0777);
            #else
                      CreateDirectory(combinedName,NULL);
            #endif
    }
 }
}
0 голосов
/ 18 ноября 2011
std::pair<bool, unsigned long> CreateDirectory(std::basic_string<_TCHAR> path)
{
    _ASSERT(!path.empty());
    typedef std::basic_string<_TCHAR> tstring;

    tstring::size_type pos = 0;

    while ((pos = path.find_first_of(_T("\\/"), pos + 1)) != tstring::npos)
    {
        ::CreateDirectory(path.substr(0, pos + 1).c_str(), nullptr);
    }

    if ((pos = path.find_first_of(_T("\\/"), path.length() - 1)) == tstring::npos)
    {
        path.append(_T("\\"));
    }

    ::CreateDirectory(path.c_str(), nullptr);

    return std::make_pair(
        ::GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES,
        ::GetLastError()
        );
}
0 голосов
/ 05 октября 2009

Интересным является требование не разбирать имя пути для имен серверов, так как кажется, что для синтаксического анализа / требуется.

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

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

0 голосов
/ 05 октября 2009

Просто пройдитесь по каждому уровню каталога по пути, начинающемуся с корня, и попытайтесь создать следующий уровень.

Если какой-либо из вызовов CreateDirectory завершится неудачно, вы можете выйти досрочно, вы добьетесь успеха, если доберетесь до конца пути без сбоев.

Предполагается, что вызов CreateDirectory по уже существующему пути не имеет вредных последствий.

...