在Java 6(不是7!)中识别依赖操作系统的无效文件名字符

在Java 6(不是7!)中识别依赖操作系统的无效文件名字符,java,filenames,Java,Filenames,现在我们已经有了一组硬编码的字符,我们检查它们--:*?“|/\--基本上就是Windows所抱怨的那些字符。但是,在Linux上运行时,这一限制太大了 我知道,在Java 7 NIO中,Path类应该足够智能,能够以依赖于操作系统的方式进行检查,如果指定了无效的文件名,就会抛出一个InvalidPathException。但是我们没有运行Java 7。在Java 6中有可靠的方法来做到这一点吗 (请注意,Windows中的新文件(“foo:bar”)看起来确实有效。但是,如果您尝试使用文件编写

现在我们已经有了一组硬编码的字符,我们检查它们--
:*?“|/\
--基本上就是Windows所抱怨的那些字符。但是,在Linux上运行时,这一限制太大了

我知道,在Java 7 NIO中,
Path
类应该足够智能,能够以依赖于操作系统的方式进行检查,如果指定了无效的文件名,就会抛出一个
InvalidPathException
。但是我们没有运行Java 7。在Java 6中有可靠的方法来做到这一点吗


(请注意,Windows中的
新文件(“foo:bar”)
看起来确实有效。但是,如果您尝试使用
文件编写器
写入新的
文件
,实际得到的是一个名为
foo
存在的空文件(文件上的
将在该点返回true,但这或多或少是谎言。)

看看Java7的源代码,然后将其中的一小部分(对于您必须支持的每个操作系统)向后移植到Java6怎么样


每个
扩展路径的系统都应该有一个类。我可以使用()快速找到的唯一源代码是,它实现了路径的功能。我认为GaeVFS对您不感兴趣,但Java7在Win32/UNIX/上实现路径的函数必须在某处可用(可能是或).

由于缺乏任何聪明的东西,以下是我的想法——不管怎么说,就是其中的精华

严格地说,可能是操作系统和文件系统的组合决定了无效的字符集,但就我而言,仅仅基于操作系统的黑客攻击似乎已经足够好了

此外,这些无效字符集是经验性的,不是官方的。Windows无效字符取自您在XP中尝试将NTFS卷上的文件重命名为无效文件时收到的错误消息。对于Unix/Linux,我认为除了路径分隔符之外,您几乎可以不使用任何东西(如果您知道得更多,请更正我)。对于MacOS,路径分隔符是
还是
/
似乎取决于文件系统——就我而言,将两者都包括在内是最安全的。(希望它们没有安装FAT或NTFS。)

List invalidIndices=newlinkedlist();
字符串无效字符;
如果(OS.isWindows()){
invalidChars=“\\/:*?\”|“;
}else if(OS.isMacOSX()){
invalidChars=“/:”;
}else{//假设为Unix/Linux
invalidChars=“/”;
}
char[]chars=filename.toCharArray();
for(int i=0;i=0)//操作系统无效
||(字符[i]<'\u0020')///ctrls
||(chars[i]>'\u007e'和&chars[i]<'\u00a0')//ctrls
) {
加入(i);
}
}
返回骰子;
注意:这是使用SwingX
OS
实用程序类来确定操作系统,但是如果没有,它也不会做任何神奇的事情——只解析
system.getProperty(“OS.name”)
文件。getCanonicalPath()将执行此操作,而不需要生成文件


只需在每个可能的字符上循环并存储结果。

我四处搜索,找到了sun.nio.fs.WindowsPathParser和sun.nio.fs.UnixPath,但它们似乎都没有做任何特别聪明的事情。考虑到如果我复制/合并GPL代码,我的老板不会欣赏我的工作,我可能也会这么做:使用NTFS的一项功能,即备用数据流。@jarekczek——它的作用是什么?我想你有一个断开的链接或者什么的。一个冒号。啊,好的。这就解释了
foo:bar
的古怪之处。谢谢
List<Integer> invalidIndices = new LinkedList<Integer>();

String invalidChars;
if (OS.isWindows()) {
    invalidChars = "\\/:*?\"<>|";
} else if (OS.isMacOSX()) {
    invalidChars = "/:";
} else { // assume Unix/Linux
    invalidChars = "/";
}

char[] chars = filename.toCharArray();
for (int i = 0; i < chars.length; i++) {
    if ((invalidChars.indexOf(chars[i]) >= 0) // OS-invalid
        || (chars[i] < '\u0020') // ctrls
        || (chars[i] > '\u007e' && chars[i] < '\u00a0') // ctrls
    ) {
        invalidIndices.add(i);
    }
}

return invalidIndices;