Opened 8 years ago

Last modified 5 years ago

#9968 new Bugs

[filesystem] Streams don't handle unicode file name on Windows

Reported by: mike@… Owned by: Beman Dawes
Milestone: To Be Determined Component: filesystem
Version: Boost 1.55.0 Severity: Problem
Keywords: mingw Cc:

Description

I want to read / write a file with a unicode file name using boost filesystem, boost locale on Windows (mingw).

This is my code:

#include <boost/locale.hpp> #define BOOST_NO_CXX11_SCOPED_ENUMS #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> namespace fs = boost::filesystem;

#include <string> #include <iostream>

int main() {

std::locale::global(boost::locale::generator().generate("")); fs::path::imbue(std::locale());

fs::path file("äöü.txt"); if (!fs::exists(file)) {

std::cout << "File does not exist" << std::endl;

}

fs::ofstream(file, std::ios_base::app) << "Test" << std::endl;

}

The fs::exists really checks for a file with the name äöü.txt. But the written file has the name äöü.txt.

Reading gives the same problem. Using fs::wofstream doesn't help either, since this just handles wide input.

So it seems the behaviour of fs::ofstream is off.

Change History (5)

comment:1 by anonymous, 8 years ago

Same problem here, I tried also utf8 and it doesn't work as well:

#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
(...)
std::locale global_loc = std::locale();
std::locale loc(global_loc, new boost::filesystem::detail::utf8_codecvt_facet);
boost::filesystem::path::imbue(loc);
(...)
boost::filesystem::ofstream hello("שלום.txt");

it creates ラゥラ慵勉・txt since I'm on SJIS encoding.

Windows machine, i686-w64-mingw32-g++ (GCC) 4.8.3 on Cygwin

comment:1 by anonymous, 8 years ago

Same problem here, I tried also utf8 and it doesn't work as well:

#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
(...)
std::locale global_loc = std::locale();
std::locale loc(global_loc, new boost::filesystem::detail::utf8_codecvt_facet);
boost::filesystem::path::imbue(loc);
(...)
boost::filesystem::ofstream hello("שלום.txt");

it creates ラゥラ慵勉・txt since I'm on SJIS encoding.

Windows machine, i686-w64-mingw32-g++ (GCC) 4.8.3 on Cygwin

comment:2 by Artyom Beilis, 7 years ago

The problem is that boost::filesystem::ofstream uses native filebuf - and mingw does not support wide path parameter so basically it fails back to narrow strings.

In these terms ofstream is not really useful under mingw.

comment:3 by anonymous, 5 years ago

Still an issue in 1.63.

Workaround: Create a temporary file with a normal name (file.tmp) and use

boost::filesystem::copy_file("file.tmp", destfile)

That is a major nuisance, though.

comment:4 by boost.flamefire@…, 5 years ago

Came across the same problem. I was wondering: If boost has to fall back to narrow character set on mingw then why doesn't it convert the filename correctly?

In my case I have to write to the user directory but the username contains an umlaut. Internally I use all UTF8 in the string (std::string) and also have the path as an UTF8 string. When I pass it to e.g. memory mapped files or the directory functions it works. In MSVC it also works (widechar open function for fstream) but on MinGW it falls back to narrow char open and (maybe?) passes the utf8 string raw into the open function instead of converting it to the system encoding.

Note: See TracTickets for help on using tickets.