【问题标题】:What characters allowed in file names on Android?Android 上的文件名中允许使用哪些字符?
【发布时间】:2011-02-10 09:41:13
【问题描述】:

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

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

另外,我可以用 Unicode 名称保存文件吗?

【问题讨论】:

  • 您的意思是在 SD 卡(或同等设备)上吗?
  • 在 Unix(以及 Android)上,只是 NULL (0x00) 和 / 是无效的。不过,对于互操作性,您可能对以下答案中的 Windows 列表感兴趣。

标签: android filenames illegal-characters


【解决方案1】:
  1. 在 Android 上(至少在默认情况下)编码为 UTF-8 的文件名。

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

我认为是保留的:

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

【讨论】:

  • '+[] 不保留
  • 没有'+[](如@xmen 所述),这实际上是 Windows 集。但它只描述了无效的 printable 字符。控制字符 0x00-0x1f0x7f 在 Windows 上也无效。对于互操作性,所有这些都可能有用。但仅在 Unix(以及 Android)上,唯一的无效字符是 NULL (0x00) 和 /
  • 来到这里研究 android 上的 firefox 下载。由于某种原因,firefox 认为加号导致文件名无效。
【解决方案2】:

根据wiki 并假设您使用的是具有 FAT32 的外部数据存储。

目录条目中允许的字符

除值 0-31、127 (DEL) 和:" * / : ? \ | + , . ; = [] 之外的任何字节(小写 az 存储为 AZ)。对于 VFAT LFN,除 NUL 之外的任何 Unicode

【讨论】:

  • "; , .=" 允许在 android 中使用文件名
  • 在外部和内部存储上都是这样吗?是否允许所有其余字符?此处显示的文本为 lowercard=uppercase(例如,这意味着我不能在同一文件夹中包含“Hello.txt”和“hello.txt”)?
【解决方案3】:
final String[] ReservedChars = {"|", "\\", "?", "*", "<", "\"", ":", ">"};

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

【讨论】:

    【解决方案4】:

    来自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 使用)。用作参考(或通过反思自担风险)

    【讨论】:

      【解决方案5】:

      对于 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;
              }  
          };
      

      【讨论】:

      • 好主意,执行不力。因为它只会在一个一个输入字符时正确过滤。如果您粘贴某些内容,则可能无法正确过滤。
      【解决方案6】:

      我在 Android 4.4.2 上的 Galaxy Note 8 上对此进行了快速测试。默认的“我的文件”应用有助于将无效字符显示为灰色,如下所示:

      ? : " * | / \

      我将所有其他可用的特殊字符放入文件名并保存。这可能在所有 Android 版本中都不一致,所以最好保守一点,用类似有意义的字符替换它们。

      【讨论】:

      • 什么是 Galaxy Note 8?尤其是在 2014 年。
      • 来自三星网站:Note Tablet
      【解决方案7】:

      这显然取决于文件系统和 Android 操作系统。在我的 oneplus/oxygenOS 上,接受答案中的唯一字符

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

      我不能用来重命名文件的是 / 和 *

      但是,在 Android 范围内,上面的列表似乎是明智的。

      【讨论】:

        【解决方案8】:

        在 Android as suggested there 上,您可以使用输入过滤器来防止用户输入无效字符,这是一个更好的实现:

        /**
         * 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
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-30
          • 1970-01-01
          • 2010-10-29
          相关资源
          最近更新 更多