java - Linux 和 OSX 以及 Android 根据区域设置的排序不一致

标签 java android bash sorting

我试图为 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/

相关文章:

java - 如何修复 'android.os.NetworkOnMainThreadException' ?

java - 使用 JUnit 对自定义 ElasticSearch 客户端进行单元测试

java - 迄今为止的字符串(格式无效)

java - 插件 com.android.ide.eclipse.adt 无法加载类 android

android - 以编程方式创建 TableLayout

android - 如何将图像按钮的背景设置为用户拍摄的照片?

java - 鼠标监听器无法与 Java 中的 JFrame 一起使用

Windows Bash 和 Visual Studio Code : How can I launch bash as a run task?

bash sed 不会替换多次出现的搜索模式

bash - 从列表或镜像中找到最快的镜像