-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
details::os::path_exists(const std::string&) doesn't handle UTF8 filename correctly under Windows #2977
Comments
It turns out removing the
Because MSVC also support If |
The character encoding of If you know that the character encoding of |
On Windows as long as SPDLOG_WCHAR_FILENAMES is not an option for me. For cross-platform development, this setup (every string is UTF8, avoid If we can remove the only odd place in Thanks. |
In my opinion, this solves the issue completely:
|
I can find |
Well, I think so. There's an
Just wrapping around some _statxxx function. |
You can send a pull request, but I am not sure if it will be accepted if you are using an API that is not officially documented. |
How about this one:
Need your opinion before sending the PR. |
Looking at the MSDN (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions?view=msvc-170#time-type-and-file-length-type-variations-of-_stat), the size of the time data and file data differs depending on |
Yes, I think so. I currently don't have a pure 32bit Windows (I don't think anyone has these days), but I can compile it to x86 mode and run as 32bit process without any problem. |
If it works, then there is no problem. |
OK, thank you very much. |
For your information. I just remembered that I used std::string file_path = "/path/to/file";
#ifdef _WIN32
file_path = std::filesystem::u8path(file_path.c_str()).string();
#endif This could be a workaround if the PR is not merged. However, |
Thank you, this is very helpful! What could I use if I happens to compile to C++20? |
It also works with C++20. |
Maybe std::filesystem::path(reinterpret_cast<const char8_t*>("utf8/encoded/path")) is the new preferred way to do the same as std::filesystem::u8path()? |
In C++20, yes. |
My application must support both Windows and Linux, so every path and filename inside the app is encoded UTF8 with std::string, and WCHAR is not used (SPDLOG_WCHAR_FILENAMES is not enabled).
But under Windows (code taken from the latest spdlog 1.13.0):
GetFileAttributesA()
will use CP_ACP (the default system code page) not CP_UTF8, which will fail if the path contains UTF8-encoded non-ascii characters.My current work around for this issue is:
But I know std::filesystem requires C++17, so it doesn't count as a general solution for spdlog.
Note for the above code to work under Windows, we need to call
setlocale(LC_ALL, ".UTF8")
at the beginning of the app (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-170#utf-8-support), so that
std::filesystem::path
will treat the pathname as UTF8 encoded string.I just open this issue for discussion, still looking for a more general solution. Thanks.
The text was updated successfully, but these errors were encountered: