Fix the Windows platform implementation of the FileSystem API #470
Fix the Windows platform implementation of the FileSystem API #470iseki0 wants to merge 16 commits intoKotlin:developfrom
Conversation
|
Another bug exists, for the long path handling. I will fix it in another PR. |
|
@iseki0 thanks for opening the PR! Is it possible to add tests reproducing issues that might occur when using mingw's opendir/readdir (and SomethingSomethingA Win32 functions)? |
I will have a try, the simpliest way is add some file/folder with non-English filename. I will add it to mingw test directory. |
@fzhinkin |
When setup Windows with the default configuration(non-English version and, <=Windows 10). The |
|
Please do squash merging. And please add a co-author which2who@gmail.com, he also made a patch but he's late😂. He notice me that the basename/dirname... should be fixed too. |
|
Many testcases failed, because the Windows separator is '\' but the posix is '/'. The testcase compare the string directly... |
|
We shouldn't compare string directly. The path string shouldn't be comparing directly. It's platform dependent. |
|
OK, I fixed the SystemPathSeparator val... Now all test passed. |
115c841 to
4d7d065
Compare
|
@fzhinkin Now, I rebased, please review it again. At least it fix the encoding problem, on Windows |
I will need an explicit consent from that person for that.
Unfortunately, there are a few test failures: https://teamcity.jetbrains.com/buildConfiguration/KotlinTools_KotlinxIo_BuildAggregated/5556685?buildTab=tests&status=failed |
@Test
fun testA(){
memScoped {
println(dirname("C:\\foo\\bar".cstr)!!.toKString())
println(dirname("C:\\foo\\bar".cstr)!!.toKStringFromUtf8())
println(dirname("C:\\啊啊啊啊\\123".cstr)!!.toKString())
println(dirname("C:\\啊啊啊啊\\123".cstr)!!.toKStringFromUtf8())
println(dirname("C:\\irohauta\\いろはにほへと\\ちりぬるを".cstr)!!.toKString())
println(dirname("C:\\irohauta\\いろはにほへと\\ちりぬるを".cstr)!!.toKStringFromUtf8())
}
}output My Windows: Default code page: 936, GBK |
|
I add a skip to the TeamCity test |
|
I think the Windows path handling still have many problems, after this PR. This only fix the encoding problem and make it basiclly available, on Windows platform. So we'd better merge it quickly. Because after that we'd better to begin to consider the following problems:
Any, maybe many others... |
|
@iseki0, sorry for the delay, and thank you for addressing all my questions/concerns. |
|
@fzhinkin OK, I wrote a basically available Windows path impl at https://github.com/iseki0/klibpath |
|
oh, shall we see a new version containing this update before next February? |
| assertEquals(Path("\\\\server\\share"), Path("\\\\server\\share\\dir").parent) | ||
| assertEquals(Path("""\\server\share"""), Path("""\\server\share\dir""").parent) | ||
| // This is a root UNC path, so parent is | ||
| assertEquals(null, Path("""\\server\share""").parent) |
There was a problem hiding this comment.
@iseki0 this assertion fails because Path("""\\server\share""").parent returns "\\server".
I suggest fixing parent's behavior separately and fixing the assertion for now.
There was a problem hiding this comment.
jshell> Path.of("\\\\server\\share").getParent()
$2 ==> nullThere was a problem hiding this comment.
Maybe this API has different behaviours on Windows and Linux...
C:\Users\iseki>jshell -version
jshell 24.0.2
C:\Users\iseki>java -version
java version "24.0.2" 2025-07-15
Java(TM) SE Runtime Environment (build 24.0.2+12-54)
Java HotSpot(TM) 64-Bit Server VM (build 24.0.2+12-54, mixed mode, sharing)
There was a problem hiding this comment.
It's kotlinx.io.files.Path, not java.nio.file.Path. It has its own implementation which is having issues with UNC paths and incorrectly determining their roots.
There was a problem hiding this comment.
Here's a problem. Different platforms have different behaviors. What should we do? Just interpreting all paths like the UNC path is Windows UNC path? Even if we're running on Linux?
There was a problem hiding this comment.
@iseki0, let's keep the incorrect behavior for now and once Pathcch library will be available from Kotlin, dirnameImpl could be updated to use PathCchRemoveFileSpec instead of PathRemoveFileSpecW (that'll fix the behavior).
There was a problem hiding this comment.
@iseki0, let's keep the incorrect behavior for now and once Pathcch library will be available from Kotlin,
dirnameImplcould be updated to usePathCchRemoveFileSpecinstead ofPathRemoveFileSpecW(that'll fix the behavior).
I don't know which decision is better. In the past month I wrote a pure Kotlin implementation of Windows path parsing and normalization... Of course for the real world io we should use Windows API directly, but for path parsing? If we depends on the Windows API we will have no chance to implement the same behaviors on non-Windows platform. I see the openjdk do it by self-made Java code. I just... In some confuse...
There was a problem hiding this comment.
Rewriting path parsing completely is indeed an option, but it is outside of the scope of this PR.
If we depends on the Windows API we will have no chance to implement the same behaviors on non-Windows platform.
Currently, kotlinx.io.files.Path represents platform-specific paths, and it is not aimed for parsing Windows paths on, for example, Android devices.
We're considering providing such cross-platform path parsing functionality as part of #241, but scenarios where it is needed are quite niche (and there are only a few of them).
| // Skipping test because console code page is UTF-8, | ||
| // use when clause because I'm not sure which codepage should be skipped | ||
| when (GetConsoleCP()) { | ||
| 65001u -> return |
There was a problem hiding this comment.
@iseki0, GetConsoleCP returns 65001 even if I run tests on a Windows machine with default code page 950 (Big5). Is some specific setup required to run this test?
There was a problem hiding this comment.
@fzhinkin IIRC, Windows 11 enable the always UTF-8 option default... But it's not true on other Windows version. (My: Microsoft Windows [Version 10.0.19045.6466])

The sentence: Beta: Use Unicode UTF-8 provide international supports...
There was a problem hiding this comment.
@iseki0, is there a reason to keep this test in the repository other than showcasing the issue with mingw's dirname? If no, let's remove it.
There was a problem hiding this comment.
Ok, just remove it. No problems.
There was a problem hiding this comment.
Ok, just remove it. No problems.
|
Any updates on this PR? I'd be glad to see this fix in the next release. |
|
nops |
|
https://github.com/SaltifyDev/ktfs A temporary workaround which wraps |
Problem
Memo
The Windows path related string should be accessed by Win32 API which with
Wsuffix, don't useAsuffix API or you will get trouble on non-English content. By mingw is also unrecommended, they always get trouble on encoding handling. So, just use the plain Win32 API, the most eaist choice.And...
I refactor your project layout, remove the
nativeNonAndroidsourceset. (The dir list code is the only code in this sourceset.)I don't think seperate the world be
xxandnonXxis a good choice. Now we need the third part......If I make something wrong, let me know.