Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание директории 
:(
    Опции темы
VSB
Дата 17.7.2010, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



Написал функцию для создания вложенных директорий, но не уверен, что правильно.
Посмотрите, пожалуйста
Код

#define MY_MAX_PATH 32768    //REAL NTFS MAX_PATH
#define UNC_PREFIX L"\\\\?\\" 


BOOL my_CreateDirectoryW(
                         __in     LPCWSTR lpPathName,
                         __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes
                         )
{
    WCHAR *tmpchr;
    WCHAR tmpDir[MY_MAX_PATH];
    wcscpy_s(tmpDir,MY_MAX_PATH,lpPathName);
    WCHAR tmpUpDir[MY_MAX_PATH];
    wcscpy_s(tmpUpDir,MY_MAX_PATH,lpPathName);
    if (wcslen(wcsrchr(tmpUpDir,L'\\'))==1)
    {
        tmpchr=wcsrchr(tmpUpDir,L'\\');
        *tmpchr=L'\0';
    } 
    tmpchr=(WCHAR *)((DWORD)wcsrchr(tmpUpDir,L'\\')+sizeof(WCHAR));                //we need the last character
    *tmpchr=L'\0';
    if (!PathFileExistsW(tmpUpDir))                                                //there is no upper directory, try to create in
    {
        if ((wcscmp(tmpUpDir,tmpDir)==0)||(wcscmp(tmpUpDir,UNC_PREFIX)==0))        //there can't be upper directory
        {
            SetLastError(ERROR_PATH_NOT_FOUND);
            return FALSE;
        } 
        else                                                                    //there can be
        {
            return my_CreateDirectoryW(tmpUpDir,lpSecurityAttributes);
        }
    }
    else
    {
        return CreateDirectoryW(tmpDir,lpSecurityAttributes);                    //hl may be created only in existing directory
    }
}


Это сообщение отредактировал(а) VSB - 17.7.2010, 12:25
PM MAIL   Вверх
586
Дата 17.7.2010, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 10
Всего: 146



А ведь такая функция есть... http://msdn.microsoft.com/en-us/library/bb...28VS.85%29.aspx
PM   Вверх
VSB
Дата 17.7.2010, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



Я знаю, но во первых
Цитата

pszPath [in] 
LPCWSTR

A pointer to a null-terminated Unicode string that contains the fully-qualified path of the directory. This string should have no more than MAX_PATH characters, including the terminating NULL character.


И ещё
Цитата

Note  This function is available through Windows XP Service Pack 2 (SP2) and Windows Server 2003. It might be altered or unavailable in subsequent versions of Windows.


Так что не подходит.
Нужна поддержка длинных путей (#define MY_MAX_PATH 32768    //REAL NTFS MAX_PATH) и работоспособность на всех NT 5.0+
PM MAIL   Вверх
boostcoder
Дата 17.7.2010, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



как-то муторно у вас получилось..
есть boost::filesystem::create_directories()

если уж очень хочется поизвращаться, то как-то так:
Код

void create_directories(const std::string& path) {
   std::string cur;
   std::vector<std::string> paths;

   if ( path[0] == '/' ) { cur += "/"; }

   boost::algorithm::split(paths, path, boost::algorithm::is_any_of("\\/"));
   for ( std::vector<std::string>::iterator it = paths.begin(); it != paths.end(); ++it ) {
      cur += *it;
      if ( !boost::filesystem::exists(cur) ) {
         boost::filesystem::create_directory(cur);
      }
      cur += "/";
   }
}


Это сообщение отредактировал(а) boostcoder - 17.7.2010, 13:13
PM WWW   Вверх
VSB
Дата 17.7.2010, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



НУ, мне нужна поддержку длинных путей (начало вида \\?\c:\...) и вход через wchar_t*
PM MAIL   Вверх
boostcoder
Дата 17.7.2010, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(VSB @ 17.7.2010,  12:51)
НУ, мне нужна поддержку длинных путей (начало вида \\?\c:\...) и вход через wchar_t*

и?

Добавлено через 55 секунд
Цитата(VSB @  17.7.2010,  12:51 Найти цитируемый пост)
\\?\c:\

а что это означает?
PM WWW   Вверх
VSB
Дата 17.7.2010, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



>а что это означает?

http://msdn.microsoft.com/en-us/library/aa...5).aspx#maxpath

Этот префикс (\\?\) при вызове к уникодным версиям некоторых функций (например, CreateDirectoryW) обойти ограничение MAX_PATH в 260 символов

Это сообщение отредактировал(а) VSB - 17.7.2010, 13:09
PM MAIL   Вверх
boostcoder
Дата 17.7.2010, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(VSB @  17.7.2010,  13:05 Найти цитируемый пост)
обойти ограничение MAX_PATH в 260 символов

в приведенном мною примере, никаких ограничений быть не может. разве что, ограничение на объем памяти smile 
PM WWW   Вверх
VSB
Дата 17.7.2010, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



Тем не менее, мне нужна полная поддержка wchar_t

Добавлено через 1 минуту и 23 секунды
Цитата(boostcoder @  17.7.2010,  13:14 Найти цитируемый пост)
в приведенном мною примере, никаких ограничений быть не может. разве что, ограничение на объем памяти  

Вы уверены?
А через какие системные вызовы оно работает на самом деле?

Это сообщение отредактировал(а) VSB - 17.7.2010, 13:22
PM MAIL   Вверх
boostcoder
Дата 17.7.2010, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(VSB @  17.7.2010,  13:22 Найти цитируемый пост)
Тем не менее, мне нужна полная поддержка wchar_t

дак замени std::string на std::wstring

Цитата(VSB @  17.7.2010,  13:22 Найти цитируемый пост)
А через какие системные вызовы оно работает на самом деле?

CreateDirectoryW()

как я понял из описания CreateDirectoryA(), для поддержки длинных путей, нужно всего лишь сделать префикс "\\?\"

в таком случае, функция приобретает вид:
Код

void create_directories(const std::wstring& path) {
   std::wstring cur(L"\\\\?\\"), tmp(path);
   std::vector<std::wstring> paths;

   std::wstring::iterator it = std::find(tmp.begin(), tmp.end(), L':');
   if ( it != tmp.end() ) {
      cur += std::wstring(tmp.begin(), it+2);
      tmp = std::wstring(it+2, tmp.end());
   }

   boost::algorithm::split(paths, tmp, boost::algorithm::is_any_of(L"\\/"));
   for ( std::vector<std::wstring>::iterator it = paths.begin(); it != paths.end(); ++it ) {
      cur += *it;
      if ( !boost::filesystem::exists(cur) ) {
         boost::filesystem::create_directory(cur);
      }
      cur += L"/";
   }
}

проверил на длине пути 4096. работает. 
PM WWW   Вверх
VSB
Дата 17.7.2010, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



И тем не менее, я ничего не знаю про boost, итераторы и не шарю в шаблонах, так что когда разберусь - может и запользую.
А пока, просто скажите, правильно ли я написал?
PM MAIL   Вверх
boostcoder
Дата 17.7.2010, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(VSB @  17.7.2010,  19:17 Найти цитируемый пост)
И тем не менее, я ничего не знаю про boost, итераторы и не шарю в шаблонах, так что когда разберусь - может и запользую.

и нафига я тут распинался? smile 
все равно спасибо.
PM WWW   Вверх
VSB
Дата 18.7.2010, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 23.8.2007

Репутация: 1
Всего: 2



Цитата(boostcoder @  17.7.2010,  20:06 Найти цитируемый пост)
и нафига я тут распинался?  


Ну извините, что так получилось.
Просто если я сейчас начну разбираться с boost и шаблонами, то не закончу этот плагин (для которого функция) в обозримом будущем.
А нужно.

Но всё равно спасибо.

=========

По функции интересует, не будет ли тут ошибок по логике (и ошибок вообще) и будет ли в результате GetLastError() соответствовать таковому от последнего вызова к CreateDirectoryW?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0851 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.