0

我写了这段代码来检查一个目录是否在 Windows 和 Unix 中都存在,但我不确定它是否正确:

int writeFiles(std::string location)
{

        // USED TO FILE SYSTEM OPERATION
        struct stat st;
        // DEFINE THE mode WHICH THE FILE WILL BE CREATED
        const char * mode = "w+b";
        /* local curl variable */

        // CHECK IF THE DIRECTORY TO WHERE THE FILE ARE GOING EXIST
        // IF NOT, CREATE IT
        if(stat(location.c_str(), &st) != 0){
                #ifndef (defined  _WIN32 || defined __WIN64)    /* WIN32 SYSTEM */
                if (!CreateDirectory(location.c_str(), NULL)){
                        std::string msg("The location directory did not exists, can't be created\n");
                        throw std::runtime_error(msg);
                }
                #elif defined __unix__          /* in the case of unix system */
                if(mkdir(location.c_str(), S_IRWXU) != 0){
                        std::string msg("The dest_loc directory did not exist, can't be created\n");
                        throw std::runtime_error(msg);
                }
                #endif

 ... more code down here.

location是应该复制文件的路径。但是,在开始复制文件之前,我必须检查目录是否存在,无论是 Windows 还是 Linux。有人可以就这个问题给我一些意见吗?谢谢

4

4 回答 4

4

预处理器指令(参见Microsoft Predefined Macros列表)我会写成:

#ifdef _WIN32

#else

// Assume UNIX system,
// depending on what you are compiling your code on,
// by that I mean you only building on Windows or UNIX
// (Linux, Solaris, etc) and not on Mac or other.
#endif

如果目录已经存在,CreateDirectory()则将失败(返回FALSE),但会将最后一个错误设置为ERROR_ALREADY_EXISTS. 更改您的使用CreateDirectory()以正确处理此问题:

if (!CreateDirectory(location.c_str(), NULL) &&
    ERROR_ALREADY_EXISTS != GetLastError())
{
    // Error message more useful if you include last error code.
    std::ostringstream err;
    err << "CreateDirectory() failure on "
        << location
        << ", last-error="
        << GetLastError();

    throw std::runtime_exception(err.str());
}

话虽如此,如果您可以访问 boost 考虑使用该boost::filesystem库。

于 2012-07-05T15:14:59.680 回答
2

你需要改变:

            #ifndef (defined  _WIN32 || defined __WIN64)    /* WIN32 SYSTEM */

到:

            #if (defined _WIN32 || defined __WIN64)    /* WIN32 SYSTEM */

这将测试是否定义了_WIN32__WIN64,如果是则使用 WINAPI 代码。

您可能还可以更改:

            #elif defined __unix__          /* in the case of unix system */

只是:

            #else          /* in the case of non-Windows system */

因为大多数非 Windows 操作系统可能有 POSIX-ish APImkdir等,而您目前没有任何其他操作系统特定的代码。

于 2012-07-05T16:19:56.173 回答
1

如果我必须编写与文件系统交互的跨平台代码,我会使用跨平台文件系统 API,例如Boost FileSystem

于 2012-07-05T15:12:45.033 回答
0

如果你可以假设 Windows 有stat(),为什么你不能也只是使用mkdir()呢?

但实际上,在 Windows 上,您可以CreateDirectory无条件调用(没有前面的stat调用)并检查是否GetLastError()返回ERROR_ALREADY_EXISTS.

此外,std::string是 ANSI 函数的匹配项,CreateDirectoryA. 使用CreateDirectory宏会使您面临 Unicode 不匹配的问题。

于 2012-07-05T15:18:19.727 回答