如何在可能不存在的目录中创建文件?

时间:2014-08-04 18:25:06

标签: c++ c file directory sdl

以下是我的情况:我使用SimpleIni打开settings.ini文件,但在某些情况下,此文件可能不存在。如果它不存在,那么我想创建它。但事实上,我需要将此文件放在用户目录中,而不是安装目录中。该文件的完整文件名是:

C:\用户\海顿\应用程序数据\漫游\公司名称\ AppName的\的Settings.ini

问题是,CompanyName文件夹可能甚至不存在。如果SimpleIni无法打开文件,那么最常见的情况是文件不存在,我想让它存在,然后再试一次(即使是空文件也可以)。

我现在使用的唯一库是SDL和SimpleIni。我想避免使用特定于平台的代码,但不希望链接到Boost。

(注意:路径字符串是由SDL创建的,在linux或mac上会有所不同)

2 个答案:

答案 0 :(得分:0)

我正在以这种方式进行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(),您可以使用mkdir以递归方式创建文件夹,轻松编写您的owm函数。在这里张贴它太长了。

答案 1 :(得分:0)

不幸的是,没有与平台无关的方法来创建目录。大多数平台都有mkdir()函数。在Windows上,您可以使用_mkdir(char *),但父目录必须存在。

因此,要创建路径,必须拆分路径,直到找到现有目录(最坏情况:从根开始)。然后创建每个子文件夹。

A"直截了当"方法是从路径的末尾循环,查找现有目录并创建所有子文件夹:

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%的错误概率。

它还假设驱动器存在。