Java-는지 여부를 확인하는 방법 파일의 이름은 유효한가요?[중복]
문제
이 질문은 이미 있는 대답을 여기:
에서 Java 응용 프로그램이 내 이름을 바꾸는 파일을 파일 이름에서 제공하는 문자열을 매개 변수입니다.는 방법이 있습니다
boolean OKtoRename(String oldName, String newName)
기본적으로 검사할지 여부를 newName 지 않는 이미 다른 파일로 내가 원하지 않을 것을 묻어 기존.
그것은 지금이 발생했는데 아마도 새 문자열을 사용하지 않을 나타내는 유효한 파일 이름입니다.그래서 저는 생각을 추가 이를 확인하는 방법:
if (new File(newName).isFile()) {
return false;
}
분명히 맞지 않을 방지하기 때문에 대부분의 경우 newFile 아직 존재하지 않고,따라서 비록 그것이 가 OKtoRename,함수는 false 를 반환합니다.
궁금,이 있습 방법(저는 알고 있지 않 java.io.파일의 개체)아 canExist()
?나 리조트 regex 을 확인하 newFile 문자열을 포함하지 않는 잘못된 문자를(예를들면?, *,",:)?이 있는지 궁금도 함수에서 어딘가에 숨겨진 JDK 는 저에게 말하면 문자열 수 있는 가능성을 나타내는 유효한 파일 이름입니다.
해결책
사용 createNewFile()
, 파일이 아직 존재하지 않는 경우에만 파일을 원자 적으로 생성합니다.
파일이 생성되면 이름이 유효하며 기존 파일을 막지 않습니다. 그런 다음 파일을 열고 데이터에서 다른 방법으로 효율적으로 복사 할 수 있습니다. FileChannel.transferXXX
운영.
일반적으로 점검과 창조물은 원자력이어야한다는 점을 명심해야합니다. 먼저 작업이 안전한지 확인하면 작업을 별도의 단계로 수행하면 그 동안 조건이 변경되었을 수 있습니다.
생각을위한 추가 음식은이 관련 게시물에서 제공됩니다. "Java에서 작업/복사."
업데이트:
이 답변 이후, Nio.2 API가 도입되어 파일 시스템과 더 많은 상호 작용을 추가했습니다.
대화식 프로그램이 있다고 가정하고 파일이 잠재적으로 유효한지 여부를 각 키 스트로크 후 확인하려고합니다. 예를 들어, "저장"을 누른 후 오류 대화 상자를 팝업하지 않고 항목이 유효한 경우에만 "저장"버튼을 활성화 할 수 있습니다. 위의 제안이 요구하는 많은 불필요한 파일을 삭제하고 삭제하는 것은 엉망인 것처럼 보입니다.
Nio.2를 사용하면 a를 만들 수 없습니다 Path
파일 시스템에 불법 인 문자가 포함 된 인스턴스. an InvalidPathException
당신이 만들려고하자마자 제기됩니다. Path
.
그러나 Windows의 "PRN"과 같은 유효한 문자로 구성된 불법 이름을 검증하는 API는 없습니다. 해결 방법으로 실험은 불법 파일 이름을 사용하면 속성에 액세스하려고 할 때 ( Files.getLastModifiedTime()
, 예를 들어).
존재하는 파일에 대한 법적 이름을 지정하면 예외는 아닙니다.
존재하지 않는 파일의 법적 이름을 지정하면 발생합니다. NoSuchFileException
.
불법 이름을 지정하는 경우 FileSystemException
제기됩니다.
그러나 이것은 매우 Kludgey처럼 보이며 다른 운영 체제에 신뢰할 수 없을 수도 있습니다.
다른 팁
나는 조립의 목록은 불법 파일이름이 문자가(고려 UNIX,Mac OS X,윈도우 시스템)에 따라 일부 온라인 연구의 몇 개월 전에.는 경우 새로운 파일 이름에 포함된 이러한 위험이 있는 유효하지 않을 수 있습니다.
private static final char[] ILLEGAL_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };
편집: 내가 좋아하는 스트레스,이 지 않은 완벽한 솔루션:으로 주석,지적했지만 이 테스트를 통과 당신의 파일 이름을 수 있습 Windows 특정 키워드를 다음과 같 COM,PRN,etc.그러나,당신의 파일 이름에 포함된 이러한 문자,그것은 확실히 문제가 발생에 크로스-플랫폼은 환경입니다.
여기 시스템 특정 방식이 제안됩니다.
public static boolean isFilenameValid(String file) {
File f = new File(file);
try {
f.getCanonicalPath();
return true;
} catch (IOException e) {
return false;
}
}
일식을 개발하는 경우 확인하십시오 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;
}
}
이것이 내가 이것을 구현 한 방법입니다.
public boolean isValidFileName(final String aFileName) {
final File aFile = new File(aFileName);
boolean isValid = true;
try {
if (aFile.createNewFile()) {
aFile.delete();
}
} catch (IOException e) {
isValid = false;
}
return isValid;
}
나에게 그것은 OS 의존적 문제 인 것 같습니다. 파일 이름에서 유효하지 않은 문자를 확인할 수 있습니다. Windows는 파일의 이름을 바꾸려고 할 때 파일에 다음 문자가 포함될 수 없다는 메시지가 표시됩니다. / : *? <> | 당신의 질문이 "도서관이 나를 위해 일하는 도서관이 있습니까?"인지 확실하지 않습니다. 이 경우 나는 아무것도 모른다.
Java 7 이후에 내가 찾은 것만 Paths
그것은 이름이라는 방법이 있습니다 get
하나 이상이 필요합니다 String
S와 던지기
InvalidPathException
- 경로 문자열을 경로로 변환 할 수없는 경우
사용
String validName = URLEncoder.encode( fileName , "UTF-8");
File newFile = new File( validName );
일을한다.
오늘 방금 찾았습니다. 100% 작동하는지 확실하지 않지만 지금까지 유효한 파일 이름을 만들 수있었습니다.