在我的Java应用程序中,我将文件重命名为String参数中提供的文件名.有一种方法
boolean OKtoRename(String oldName, String newName)
Run Code Online (Sandbox Code Playgroud)
它基本上检查newName是否已被其他文件占用,因为我不想埋没现有文件.
现在我想到,newName String可能不会表示有效的文件名.所以我想把这个检查添加到方法中:
if (new File(newName).isFile()) {
return false;
}
Run Code Online (Sandbox Code Playgroud)
这显然不是正确的方法,因为在大多数情况下newFile尚不存在,因此虽然它是 OKtoRename,但该函数返回false.
我在想,有没有一种方法(我知道有没有针对java.io.File的对象)canExist()吗?或者,我将不得不诉诸正则表达式来确保NEWFILE String不包含无效字符(如?,*," :)?我不知道是否有可能是某个地方隐藏在JDK的函数,将一个字符串告诉我可能表示有效的文件名.
Zso*_*rök 58
几个月前,我根据一些在线研究收集了一份非法文件名字符列表(考虑UNIX,Mac OS X和Windows系统).如果新文件名包含其中任何一个,则存在在所有平台上可能无效的风险.
private static final char[] ILLEGAL_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };
Run Code Online (Sandbox Code Playgroud)
编辑: 我想强调,这不是一个完整的解决方案:作为一个评论者指出,即使它通过了这个测试,你的文件名仍然可以是一个Windows特定的关键字,如COM,PRN等.但是,如果你的文件name包含任何这些字符,它肯定会在跨平台环境中造成麻烦.
eri*_*son 23
使用createNewFile(),只有在文件尚不存在时才会自动创建文件.
如果创建了该文件,则该名称有效,并且不会破坏现有文件.然后,您可以打开文件,并通过FileChannel.transferXXX操作有效地将数据从一个文件复制到另一个文件.
重要的是要记住,一般来说,检查和创建应该是原子的.如果您首先检查操作是否安全,则作为单独的步骤执行操作,同时条件可能已更改,从而使操作不安全.
这篇相关文章提供了额外的思考:"Java中的移动/复制操作".
更新:
从这个答案开始,我们引入了NIO.2 API,它们增加了与文件系统的更多交互.
假设您有一个交互式程序,并希望在每次击键后验证文件是否可能有效.例如,您可能只想在条目有效时启用"保存"按钮,而不是在按"保存"后弹出错误对话框.创建并确保删除我上面建议的许多不必要的文件似乎是一团糟.
使用NIO.2,您无法创建Path包含对文件系统非法的字符的实例.InvalidPathException一旦你尝试创建,就会引发一个Path.
但是,没有用于验证由有效字符组成的非法名称的API,例如Windows上的"PRN".作为一种解决方法,实验表明,在尝试访问属性时,使用非法文件名会引发一个明显的异常(Files.getLastModifiedTime()例如,使用).
如果为存在的文件指定合法名称,则不会出现异常.
如果为不存在的文件指定合法名称,则会引发该名称NoSuchFileException.
如果指定了非法名称,FileSystemException则引发.
但是,这看起来非常糟糕,在其他操作系统上可能不可靠.
Max*_*zin 19
这里建议使用系统特定的方法.
public static boolean isFilenameValid(String file) {
File f = new File(file);
try {
f.getCanonicalPath();
return true;
} catch (IOException e) {
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
如果开发Eclipse,请查看 org.eclipse.core.internal.resources.OS
public abstract class OS {
private static final String INSTALLED_PLATFORM;
public static final char[] INVALID_RESOURCE_CHARACTERS;
private static final String[] INVALID_RESOURCE_BASENAMES;
private static final String[] INVALID_RESOURCE_FULLNAMES;
static {
//find out the OS being used
//setup the invalid names
INSTALLED_PLATFORM = Platform.getOS();
if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
//valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp
INVALID_RESOURCE_CHARACTERS = new char[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
INVALID_RESOURCE_BASENAMES = new String[] {"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
"com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
"lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
Arrays.sort(INVALID_RESOURCE_BASENAMES);
//CLOCK$ may be used if an extension is provided
INVALID_RESOURCE_FULLNAMES = new String[] {"clock$"}; //$NON-NLS-1$
} else {
//only front slash and null char are invalid on UNIXes
//taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html
INVALID_RESOURCE_CHARACTERS = new char[] {'/', '\0',};
INVALID_RESOURCE_BASENAMES = null;
INVALID_RESOURCE_FULLNAMES = null;
}
}
/**
* Returns true if the given name is a valid resource name on this operating system,
* and false otherwise.
*/
public static boolean isNameValid(String name) {
//. and .. have special meaning on all platforms
if (name.equals(".") || name.equals("..")) //$NON-NLS-1$ //$NON-NLS-2$
return false;
if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
//empty names are not valid
final int length = name.length();
if (length == 0)
return false;
final char lastChar = name.charAt(length-1);
// filenames ending in dot are not valid
if (lastChar == '.')
return false;
// file names ending with whitespace are truncated (bug 118997)
if (Character.isWhitespace(lastChar))
return false;
int dot = name.indexOf('.');
//on windows, filename suffixes are not relevant to name validity
String basename = dot == -1 ? name : name.substring(0, dot);
if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase()) >= 0)
return false;
return Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase()) < 0;
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
77227 次 |
| 最近记录: |