От новичка до гуру: Курсы программирования на CyberDuff

Как создать файл в каталоге, который может не существовать?

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

C:\Users\Haydn\AppData\Roaming\CompanyName\AppName\settings.ini

Проблема в том, что папка CompanyName может даже не существовать. Если SimpleIni не может открыть файл, то чаще всего файл не существует, и я хочу, чтобы он существовал, а затем повторил попытку (даже пустой файл работает).

Единственные библиотеки, которые я сейчас использую, это SDL и SimpleIni. Я хочу избежать использования кода, зависящего от платформы, но предпочитаю не ссылаться на Boost.

(Примечание: эта строка пути была создана SDL, она будет другой в Linux или Mac)

04.08.2014

Ответы:


1

Я делаю чтение/запись INI таким образом (когда файл Ini находится внутри папки приложения):

void CDlgApplication::ReadSettings()
{
     CString IniPath = m_appDir ;
     IniPath += _T("Settings.ini") ;

     if(!FileExists(IniPath))
       return ;

     CIniReader iniReader(IniPath);
     //... do the settings read....
 }


 void CDlgApplication::SaveSettings()
 {
    GetParams();

    CString IniPath = m_appDir ;
    IniPath += _T("Settings.ini") ;
    CIniWriter iniWriter(IniPath);

    //... do the settings save....
 }

Где:

 bool FileExists(LPCTSTR szPath) 
 {  
    DWORD dwAttrib = GetFileAttributes(szPath); 
    return (bool)((dwAttrib != -1) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
 } 

В вашем случае, если файл INI находится в папке, отличной от папки приложения, и вы не уверены, что эта папка существует, вы можете указать путь к папке для SaveSettings() и использовать некоторый API, например Win32 MakeSureDirectoryPathExists():

 void CDlgApplication::SaveSettings(const TCHAR* OutputFolder)
 {
    if(!MakeSureDirectoryPathExists(OutputFolder))
      return ; //Maybe report error or save the INI somewhere else

    GetParams();

    CString IniPath =OutputFolder ;
    IniPath += _T("Settings.ini") ;
    CIniWriter iniWriter(IniPath);

    //... do the settings save....
 }

Если у вас нет MakeSureDirectoryPathExists(), вы можете легко написать свою функцию owm, рекурсивно создавая папки, используя mkdir. Это слишком долго, чтобы размещать это здесь.

04.08.2014
  • Я не использую WinAPI. Я использую SDL для работы с окнами, а все остальное обрабатываю по мере необходимости. Мне нужно, чтобы мое решение было кроссплатформенным. Однако я посмотрю на mkdir. 05.08.2014
  • См.: stackoverflow.com/questions/675039/, я не проверял, но кажется кроссплатформенным. 05.08.2014

  • 2

    К сожалению, не существует независимого от платформы способа создания каталога. Большинство платформ будут иметь функцию mkdir(). В Windows вы можете использовать _mkdir(char*), но родительский каталог должен существовать.

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

    «Прямой» способ - вернуться назад с конца пути, найти существующий каталог и создать все подпапки:

    size_t slashPos = 0;
    size_t lastSlashPos = 0;
    
    size_t I = strlen(filepath) + 1;
    size_t i;
    
    for (i = I-1; i<I; --i) {
        if (filepath[i] == '\\') {
            if (lastSlashPos) filepath[lastSlashPos] = '\\'
            lastSlashPos = slashPos;
            slashPos = i;
            filepath[i] = 0;
            if (/*test for filePath existance*/) {
                break;
            }
        }
    }
    
    for (; i<I; ++i) {
        if (filepath[i] == '\\') {
            if (lastSlashPos) filepath[lastSlashPos] = '\\'
            lastSlashPos = slashPos;
            slashPos = i;
            filepath[i] = 0;
            _mkdir(filepath); //TODO : Test for success
        }
    }
    
    if (lastSlashPos) filepath[lastSlashPos] = '\\'; //if you need to restore the original string
    

    Этот код был импровизирован при написании этого ответа и с вероятностью 80% может быть неверным.

    Также предполагается, что диск существует.

    04.08.2014
    Новые материалы

    5 простых концепций Python, ставших сложными
    #заранее извините 1) Переменные x = 4 y = 5 Переменная в Python — это символическое представление объекта. После присвоения некоторого объекта переменной Python мы приобретаем..

    «Освоение вероятности: изучение совместной, предельной, условной вероятности и теоремы Байеса —…
    Виды вероятности: Совместная вероятность Предельная вероятность Условная вероятность Диаграмма Венна в вероятностях: В “Set Theory” мы создаем диаграмму Венна...

    Основы Spring: Bean-компоненты, контейнер и внедрение зависимостей
    Как лего может помочь нашему пониманию Когда мы начинаем использовать Spring, нам бросают много терминов, и может быть трудно понять, что они все означают. Итак, мы разберем основы и будем..

    Отслеживание состояния с течением времени с дифференцированием снимков
    Время от времени что-то происходит и революционизирует часть моего рабочего процесса разработки. Что-то более забавное вместо типичного утомительного и утомительного процесса разработки. В..

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

    Игра в прятки с данными
    Игра в прятки с данными Я хотел бы, чтобы вы сделали мне одолжение и ответили на следующие вопросы. Гуглить можно в любое время, здесь никто не забивается. Сколько регионов в Гане? А как..

    «Раскрытие математических рассуждений с помощью Microsoft MathPrompter и моделей больших языков»
    TL;DR: MathPrompter от Microsoft показывает, как использовать математические рассуждения с большими языковыми моделями; 4-этапный процесс для улучшения доверия и рассуждений в математических..