Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open a file with unicode path

Tags:

c++

unicode

boost

I'm working under windows 7 with mingw. I have encountered some weird behaviour with unicode filenames. My program needs to be portable, and I'm using boost::filesystem (v 1.53) to handle the file paths.

This has all been going well, until I needed to open files with unicode filenames. This is not about the content of the file, but the file's name.

I tried the following: For testing I made a folder named C:\UnicodeTest\вячеслав and I tried creating a file inside of it, by appending the file name test.txt to the boost wpath. For some reason the creation of the file fails. I'm using boost's fstreams and when I try to open the file, the failbit of the stream is set. Now the funny thing is, that when I append a foldername to the path instead, a call to create_directories() succeeds and creates the correct directory C:\UnicodeTest\вячеслав\folder.

I really don't understand why it won't work with a file. This is the code I use:

boost::filesystem::wpath path;

// find the folder to test
boost::filesystem::wpath dirPath = "C:\\UnicodeTest";
vector<boost::filesystem::wpath> files;
copy(boost::filesystem::directory_iterator(dirPath), boost::filesystem::directory_iterator(), back_inserter(files));

for(boost::filesystem::wpath &file : files)
{
    if(boost::filesystem::is_directory(file))
    {
        path = file;
        break;
    }
}

// create a path for the folder
boost::filesystem::wpath folderPath = path / "folder";
// this works just fine
boost::filesystem::create_directories(folderPath);

// create a path for the file
boost::filesystem::wpath filePath = path / "test.txt";

boost::filesystem::ofstream stream;

// this fails
stream.open(filePath);

if(!stream)
{
    cout << "failed to open file " << path << endl;
}
else
{
    cout << "success" << endl;
}
like image 307
Koonschi Avatar asked Oct 22 '22 08:10

Koonschi


1 Answers

If I understand the issue correctly, the issue of being unable to create a file directly within C:\UnicodeTest\вячеслав occurs when you do not create the folder directory, as illustrated below.

// create a path for the folder
//boost::filesystem::wpath folderPath = path / "folder";
// this works just fine
//boost::filesystem::create_directories(folderPath);

// create a path for the file
boost::filesystem::wpath filePath = path / "test.txt";

I was able to get this to work by making the filename a wchar_t string:

// create a path for the file
boost::filesystem::wpath filePath = path / L"test.txt";
like image 144
Gary Sanders Avatar answered Nov 03 '22 00:11

Gary Sanders