다음은 내 경로가 알려져 있고 상대 경로가 디스크의 경로와 다른 경우가있는 상황을위한 Java 7 솔루션입니다.예를 들어
파일 /tmp/foo/biscuits
주어진 방법이 제대로 다음 입력을 파일에 Path
를 반환 :
/tmp
및 foo/biscuits
/tmp
및 foo/BISCUITS
/tmp
및 FOO/BISCUITS
/tmp
및 FOO/biscuits
이 솔루션은 이 아니며, 신뢰성있게 테스트되었으므로 프로덕션 준비 완료 스 니펫보다는 시작점으로 고려해야합니다.
/**
* Returns an absolute path with a known parent path in a case-insensitive manner.
*
* <p>
* If the underlying filesystem is not case-sensitive or <code>relativeChild</code> has the same
* case as the path on disk, this method is equivalent to returning
* <code>parent.resolve(relativeChild)</code>
* </p>
*
* @param parent parent to search for child in
* @param relativeChild relative child path of potentially mixed-case
* @return resolved absolute path to file, or null if none found
* @throws IOException
*/
public static Path getCaseInsensitivePath(Path parent, Path relativeChild) throws IOException {
// If the path can be resolved, return it directly
if (isReadable(parent.resolve(relativeChild))) {
return parent.resolve(relativeChild);
}
// Recursively construct path
return buildPath(parent, relativeChild);
}
private static Path buildPath(Path parent, Path relativeChild) throws IOException {
return buildPath(parent, relativeChild, 0);
}
/**
* Recursively searches for and constructs a case-insensitive path
*
* @param parent path to search for child
* @param relativeChild relative child path to search for
* @param offset child name component
* @return target path on disk, or null if none found
* @throws IOException
*/
private static Path buildPath(Path parent, Path relativeChild, int offset) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(parent)) {
for (Path entry : stream) {
String entryFilename = entry.getFileName().toString();
String childComponent = relativeChild.getName(offset).toString();
/*
* If the directory contains a file or folder corresponding to the current component of the
* path, either return the full path (if the directory entry is a file and we have iterated
* over all child path components), or recurse into the next child path component if the
* match is on a directory.
*/
if (entryFilename.equalsIgnoreCase(childComponent)) {
if (offset == relativeChild.getNameCount() - 1 && Files.isRegularFile(entry)) {
return entry;
}
else if (Files.isDirectory(entry)) {
return buildPath(entry, relativeChild, offset + 1);
}
}
}
}
// No matches found; path can't exist
return null;
}
네, 그 가능성은 있지만 경로의 디렉토리가 잘못된 경우에도 문제가 계속 존재합니다. 솔루션은 대소 문자를 구분하지 않고 검색하는 디렉토리 트리를 따라가는 일종의 재귀 알고리즘이 될 수 있습니다. 하지만 더 나은 솔루션을 찾고 있습니다! – jwaddell
@jwaddell : 파일 이름/경로가 어떤 케이스 에나있을 수 있고 리눅스 OS가 대소 문자를 구분하여 처리하기 때문에 더 나은 해결책이 없다고 생각합니다. –
마지 못해이 솔루션과 재귀 적 경로 검사를 구현할 것 같습니다. – jwaddell