我正在尝试在没有 NIO 的情况下抓取 Android 设备的整个文件系统(包括目录和文件)来构建它的树。如果我有 NIO,那么我可以使用 WalkTree 或类似的,但我没有。
我遇到的问题(在 Nexus 5 API 23 x86 模拟器上)是/sys/bus/pci/devices
以及可能的其他目录(例如/proc/self
) - 在应用程序超时/退出/崩溃(未知)之前它不会完成,可能会进入某种循环或其他东西(路径可能会以重复的方式改变,但规范路径变化很小或根本没有变化) 。
但是,如果我排除符号链接,那么这个问题就会消失,但我得到的只是设备上的部分文件,而不是全部 - 例如,缺少文件/data
(or /data/media/0
)以及那些没有显示在其他地方的文件 - 更不用说它看起来与大多数文件管理器显示的文件系统完全不同。前者很奇怪,因为我知道符号链接指向文件系统中仍然存在的文件和文件夹,但只是让它们看起来好像在其他地方。
解决办法是什么?我是否必须编写异常或特殊处理代码/sys/bus/pci/devices
, /proc/self
和别的?如果可以的话,我希望保留符号链接,并且希望爬网尽可能多的文件和文件夹(因此不首选从子文件夹开始)。
还有一些可能影响我最终采取的方法的相关问题 - 如果我保留符号链接,那么这是否意味着某些内容将被抓取两次或更多次?有办法避免这种情况吗?除了遵循 SymLink 并检查 CanonicalPath 之外,是否有其他方法可以检测某物何时是 SymLink 的目标?
这是我的代码:
我得到了根(我知道在 Android 中,第一个且可能是唯一的根是有效的):
File[] roots = File.listRoots();
String rootPath = "";
try {
rootPath = roots[0].getCanonicalPath();
} catch (IOException e) {
// do something
}
然后我开始爬行(注意选择是否忽略 simlinks 的布尔值):
try {
// check if the rootPath is null or empty, and then...
File rootFile = new File(rootPath);
rootNode = new FileFolderNode(rootFile, null, true, false); // last param may be true to ignore sim links
//FileFolderNode(String filePath, FileFolderNode parent, boolean addChildren, boolean ignoreSimLinks)
} catch (Exception e) {
// do something
}
它使用 FileFolderNode,它有构造函数:
public FileFolderNode(File file, FileFolderNode parent, boolean addChildren, boolean ignoreSimLinks) throws IOException {
if (file == null)
throw new IOException("File is null in new FileFolderNode");
if (!file.exists())
throw new IOException("File '" + file.getName() + "' does not exist in new FileFolderNode");
// for now this uses isSymLink() from https://svn.apache.org/repos/asf/commons/_moved_to_git/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java adjusted a bit to remove Java 7 and Windows mentions
if (!ignoreSimLinks)
if (FileUtils.isSymlink(file))
return;
this.name = file.getName();
if (this.name.equals("") && ! file.getCanonicalPath().equals("/"))
throw new IOException("Name is empty in new FileFolderNode");
this.isDirectory = file.isDirectory();
if (this.isDirectory) {
this.children = new ArrayList<FileFolderNode>();
if (addChildren) {
File[] files = file.listFiles();
if (files == null) {
// do something
} else {
// add in children
for (File f : files) {
FileFolderNode child = null;
try {
child = new FileFolderNode(f, this, addChildren, ignoreSimLinks);
} catch (Exception e) {
child = null;
}
if (child != null)
children.add(child);
}
}
}
}
}
鉴于这里缺乏答案,我已将这个问题分解为需要澄清的区域,并试图找到这些问题的答案 - 请看看您是否可以帮助解决这些问题:
获取Android文件系统root https://stackoverflow.com/questions/59606203/get-android-filing-system-root
Android 符号链接到隐藏或单独的位置或分区 https://stackoverflow.com/questions/59606639/android-symlinks-to-hidden-or-separate-locations-or-partitions
避免 Android 符号链接循环 https://stackoverflow.com/questions/59678418/avoiding-android-symbolic-link-loop