[英]Check if file is in (sub)directory
我想检查现有文件是否位于特定目录或该目录的子目录中。
我有两个文件对象。
File dir;
File file;
两者都保证存在。 让我们假设
dir = /tmp/dir
file = /tmp/dir/subdir1/subdir2/file.txt
我希望这张支票返回真
现在我正在以这种方式进行检查:
String canonicalDir = dir.getCanonicalPath() + File.separator;
boolean subdir = file.getCanonicalPath().startsWith(canonicalDir);
这似乎适用于我有限的测试,但我不确定这是否会在某些操作系统上产生问题。 我也不喜欢 getCanonicalPath() 会抛出我必须处理的 IOException。
有没有更好的办法? 可能在某个图书馆?
谢谢
除了来自rocketboy的asnwer之外,使用getAbsolutePath()
getCanonicalPath()
instad使\\dir\\dir2\\..\\file
转换为\\dir\\file
:
boolean areRelated = file.getCanonicalPath().contains(dir.getCanonicalPath() + File.separator);
System.out.println(areRelated);
要么
boolean areRelated = child.getCanonicalPath().startsWith(parent.getCanonicalPath() + File.separator);
不要忘记使用try {...} catch {...}
捕获任何Exception
。
注意:您可以使用FileSystem.getSeparator()
而不是File.separator
。 执行此操作的“正确”方法是将要作为String
检查的目录的getCanonicalPath()
获取,然后检查是否以File.separator
结束,如果没有,则将File.separator
添加到结尾该String
,以避免双斜杠。 这样,如果Java决定最后返回带有斜杠的目录,或者如果您的目录字符串来自Java.io.File
以外的其他地方,则可以跳过将来的奇怪行为。
注意2:Thanx到@david指向File.separator
问题。
我会创建一个小实用程序方法:
public static boolean isInSubDirectory(File dir, File file) {
if (file == null)
return false;
if (file.equals(dir))
return true;
return isInSubDirectory(dir, file.getParentFile());
}
这个方法看起来很稳固:
/**
* Checks, whether the child directory is a subdirectory of the base
* directory.
*
* @param base the base directory.
* @param child the suspected child directory.
* @return true, if the child is a subdirectory of the base directory.
* @throws IOException if an IOError occured during the test.
*/
public boolean isSubDirectory(File base, File child)
throws IOException {
base = base.getCanonicalFile();
child = child.getCanonicalFile();
File parentFile = child;
while (parentFile != null) {
if (base.equals(parentFile)) {
return true;
}
parentFile = parentFile.getParentFile();
}
return false;
}
它与dacwe的解决方案类似,但不使用递归(尽管在这种情况下不应该有很大的不同)。
如果您计划使用文件和文件名,请检查apache fileutils和filenameutils库。 充满了实用性(以及portale,如果可移植性是matdatory)功能
public class Test {
public static void main(String[] args) {
File root = new File("c:\\test");
String fileName = "a.txt";
try {
boolean recursive = true;
Collection files = FileUtils.listFiles(root, null, recursive);
for (Iterator iterator = files.iterator(); iterator.hasNext();) {
File file = (File) iterator.next();
if (file.getName().equals(fileName))
System.out.println(file.getAbsolutePath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
您可以从特定DIR开始遍历文件树。 在Java 7中,有Files.walkFileTree
方法。 您只需编写自己的访问者来检查当前节点是否是搜索文件。 更多doc: http : //docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#walkFileTree%28java.nio.file.Path,%20java.util.Set,%20int ,%20java.nio.file.FileVisitor%29
你可以这样做,但它不会捕获每个用例,例如dir = / somedir /../tmp / dir / etc ...,除非这也是文件的定义方式。
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileTest {
public static void main(final String... args) {
final Path dir = Paths.get("/tmp/dir").toAbsolutePath();
final Path file = Paths.get("/tmp/dir/subdir1/subdir2/file.txt").toAbsolutePath();
System.out.println("Dir: " + dir);
System.out.println("File: " + file);
final boolean valid = file.startsWith(dir);
System.out.println("Valid: " + valid);
}
}
为了使检查正常工作,您确实需要使用toRealPath()
或在您的示例中为getCanonicalPath()
映射这些,但是您必须处理这些示例的异常,这是绝对正确的,您应该这样做。
由于 Java 7+ 你可以这样做:
file.toPath().startsWith(dir.toPath());
比较路径怎么样?
boolean areRelated = file.getAbsolutePath().contains(dir.getAbsolutePath());
System.out.println(areRelated);
要么
boolean areRelated = child.getAbsolutePath().startsWith(parent.getAbsolutePath())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.