安卓文件名允许使用哪些字符?

56

在Android上,文件名允许使用哪些特殊字符?

~!@#$%^&*()_+/\.,

此外,我可以保存具有Unicode名称的文件吗?


3
你的意思是指SD卡(或同等设备)吗? - Nicolas Raoul
2
https://superuser.com/a/693819/687273 - user6796473
4
在Unix(包括Android)中,无效的字符是NULL0x00)和/。为了实现互操作性,您可能会对下面答案中的Windows列表感兴趣。 - caw
8个回答

41
  1. 在Android上(至少默认情况下),文件名以UTF-8编码。

  2. 看起来保留的文件名字符取决于挂载的文件系统(http://en.wikipedia.org/wiki/Filename)。

我认为以下字符是保留的:

private static final String ReservedChars = "|\\?*<\":>+[]/'";

12
+[]不是保留值。 - xmen
3
如@xmen所指出的,没有'+[]',这实际上是Windows字符集。但它仅描述无效的可打印字符。在Windows上,控制字符0x00-0x1f0x7f也是无效的。为了实现互操作性,这可能很有用。但是在Unix(因此也是Android)上,唯一无效的字符是NULL0x00)和/ - caw
1
来这里研究在安卓上下载Firefox。由于某种原因,Firefox认为加号会导致无效的文件名。 - GGets

18

来自android.os.FileUtils

的内容。

    private static boolean isValidFatFilenameChar(char c) {
        if ((0x00 <= c && c <= 0x1f)) {
            return false;
        }
        switch (c) {
            case '"':
            case '*':
            case '/':
            case ':':
            case '<':
            case '>':
            case '?':
            case '\\':
            case '|':
            case 0x7F:
                return false;
            default:
                return true;
        }
    }
    private static boolean isValidExtFilenameChar(char c) {
        switch (c) {
            case '\0':
            case '/':
                return false;
            default:
                return true;
        }
    }

注意: FileUtils是隐藏的API(不适用于应用程序; 仅供AOSP使用)。使用时可以作为参考(或通过反射自行承担风险)。


10
根据维基百科和假设您使用的外部数据存储为FAT32,目录条目中允许的字符为任何字节,但排除值为0-31、127(DEL)以及:" * / : < > ? \ | + , . ; = [](小写字母a-z将被存储为A-Z)。使用VFAT LFN时,除NUL外任何Unicode都可以。

1
在安卓中,文件名允许使用 "; , . = " 这些字符。 - fire in the hole
这是在外部和内部存储上都成立的吗?其余所有字符都允许吗?小写字母=大写字母,就像文本所显示的那样(例如,我不能在同一文件夹中拥有“Hello.txt”和“hello.txt”)? - android developer

7
final String[] ReservedChars = {"|", "\\", "?", "*", "<", "\"", ":", ">"};

for(String c :ReservedChars){
    System.out.println(dd.indexOf(c));
    dd.indexOf(c);
}

6

这是Android中用于文件名的正确InputFilter

    InputFilter filter = new InputFilter()
    {
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) 
        { 
            if (source.length() < 1) return null;
            char last = source.charAt(source.length() - 1);
            String reservedChars = "?:\"*|/\\<>";
            if(reservedChars.indexOf(last) > -1) return source.subSequence(0, source.length() - 1);
            return null;
        }  
    };

好主意,实现不佳。目前只能在逐个输入字符时才能正确过滤。如果你粘贴了一些内容,很有可能无法正确过滤。 - Slion

3

这显然取决于文件系统和Android操作系统。在我的OnePlus/OxygenOS上,接受的答案中只有这些字符

private static final String ReservedChars = "|\\?*<\":>+[]/'";

我无法使用 / 和 * 用于文件重命名。

然而,在 Android 广泛使用的情况下,上述列表似乎是合理的。


2
我在安卓4.4.2上快速测试了我的Galaxy Note 8。默认的My Files应用程序会将无效字符变灰,这些字符如下:

? : " * | / \ < >

我将所有其他特殊字符放入文件名中并保存了下来。这可能在所有安卓版本中不一致,因此最好保守一些,用类似含义的字符替换它们。

2
什么是Galaxy Note 8?特别是在2014年。 - Marc DiMillo
2
从三星网站:Note Tablet - TopherC

2

在Android上,建议使用输入过滤器来防止用户输入无效字符,以下是更好的实现方式:

/**
 * An input filter which can be attached to an EditText widget to filter out invalid filename characters
 */
class FileNameInputFilter: InputFilter
{
override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? {
    if (source.isNullOrBlank()) {
        return null
    }

    val reservedChars = "?:\"*|/\\<>\u0000"
    // Extract actual source
    val actualSource = source.subSequence(start, end)
    // Filter out unsupported characters
    val filtered = actualSource.filter { c -> reservedChars.indexOf(c) == -1 }
    // Check if something was filtered out
    return if (actualSource.length != filtered.length) {
        // Something was caught by our filter, provide visual feedback
            if (actualSource.length - filtered.length == 1) {
                // A single character was removed
                BrowserApp.instance.applicationContext.toast(R.string.invalid_character_removed)
            } else {
                // Multiple characters were removed                    
     BrowserApp.instance.applicationContext.toast(R.string.invalid_characters_removed)
                }
            // Provide filtered results then
            filtered
        } else {
            // Nothing was caught in our filter
            null
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接