我试图为 Android、Linux 和 OSX 获得相同的排序顺序。 我正在比较 Linux 和 OSX 的排序命令结果 因此,Android 上的自定义代码可在类似的文件集上运行。
在 Linux/OSX 上我使用这个命令:
find {folder_name} -type f | sort
在 java/android 中我正在使用这个 - 但排序顺序 不对齐:
private Enumeration<InputStream> getSortedStreams(HashMap<String,InputStream> collection) {
Vector<InputStream> fileSreams = new Vector<>();
List<String> keys = new ArrayList(collection.keySet());
Collator collator = Collator.getInstance(Locale.US);//<<???
Collections.sort(keys,collator);
for (String key: keys) {
Log.d(TAG, "getSortedStreams: " + key);
fileSreams.add(collection.get(key));
}
return fileSreams.elements();
}
Android 输出:
1000/abc_d.txt
1000/abc-d.txt
OSX 输出:
1000/abc-d.txt
1000/abc_d.txt
我假设差异是由于使用的区域设置造成的 对文件列表进行排序。据我所知,OSX 和 Linux 都是 尽管 Linux 未经过认证,但仍符合 POSIX 标准。 Android 也不兼容 POSIX,但我猜它在排序方面没问题。
我在下面提供了一些详细信息,试图让其有意义并获得一致的结果 跨平台经验。
看来我可以控制Linux和Android对齐,但OSX忽略我设置的环境变量。
我需要特定的帮助来设置区域设置,以便获得一致的结果 跨平台。
我还没有在IOS上做过测试,如果需要我可以提交。
更多详细信息:
在 Fedora Core 上。
测试用例: 在名为 sort_test 的目录中创建两个具有以下名称的文件
sort_test/abc_d.txt
sort_test/abc-d.txt
在 Fedora Linux Core 17 上 - 3.9.10-100.fc17.x86_64
en_US 的语言环境 -a 是:
locale -a | grep en_US
en_US
en_US.iso88591
en_US.iso885915
en_US.utf8
使用 C
find sort_test/ -type f | env -i LC_COLLATE=C sort
sort_test/abc-d.txt
sort_test/abc_d.txt
使用 en_US.utf8
find sort_test/ -type f | env -i LC_COLLATE=en_US.utf8 sort
sort_test/abc_d.txt
sort_test/abc-d.txt
在 OSX 上 - 似乎很困惑,设置区域设置没有效果:
local -a 给出区域设置列表,en_US 区域设置为:
en_US
en_US.ISO8859-1
en_US.ISO8859-15
en_US.US-ASCII
en_US.UTF-8
使用 C
find sort_test -type f | env -i LC_COLLATE=C sort
sort_test/abc-d.txt
sort_test/abc_d.txt
使用 en_US.UTF-8
find sort_test -type f | env -i LC_COLLATE=en_US.UTF-8 sort
sort_test/abc-d.txt
sort_test/abc_d.txt
在 Android 上,我将区域设置设置为使用 POSIX 区域设置:
Locale locale = new Locale("en", "US", "POSIX");<<< the fix
Collator collator = Collator.getInstance(locale);
Collections.sort(keys,collator);
for (String key: keys) {
Log.d(TAG, "getSortedStreams: " + key);
fileStreams.add(collection.get(key));
}
/1000/abc-d.txt
/1000/abc_d.txt
在 Android 上,我将区域设置设置为美国:
//Locale locale = new Locale("en", "US", "POSIX");
Collator collator = Collator.getInstance(Locale.US);
Collections.sort(keys,collator);
for (String key: keys) {
Log.d(TAG, "getSortedStreams: " + key);
fileStreams.add(collection.get(key));
}
/1000/abc_d.txt
/1000/abc-d.txt
LINUX 语言环境变量为:语言环境命令输出:
LANG=en_US.UTF-8
LC_CTYPE=UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
OSX 区域设置变量为:区域设置命令输出:
LANG=
LC_COLLATE="C"
LC_CTYPE="UTF-8"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=
最佳答案
目前似乎对我有用的解决方案是将所有操作系统与 OSX 保持一致。
Linux:
find sort_test -type f | env -i LC_COLLATE=C sort
OSX:
find sort_test -type f | env -i LC_COLLATE=C sort
Android:
Locale locale = new Locale("en", "US", "POSIX");<<< the fix
Collator collator = Collator.getInstance(locale);
Collections.sort(keys,collator);
关于java - Linux 和 OSX 以及 Android 根据区域设置的排序不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35630373/