Opened 8 years ago
Last modified 5 years ago
#9968 new Bugs
[filesystem] Streams don't handle unicode file name on Windows
Reported by: | 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 , 8 years ago
comment:1 by , 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 , 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 , 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 , 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.
Same problem here, I tried also utf8 and it doesn't work as well:
it creates ラゥラ慵勉・txt since I'm on SJIS encoding.
Windows machine, i686-w64-mingw32-g++ (GCC) 4.8.3 on Cygwin