它基本上归结为:如果我在一个目录中有 4000 个文件,则 File.isDirectory() 函数需要 1ms 来执行,因此该目录需要 4s 来计算(太慢 [1])。
我没有最完整的文件系统知识,但我认为 isDirectory() 可以针对目录中的所有元素进行批处理(读取一大块数据,然后分离单个文件的元数据)。 C/C++ 代码是可接受的(它可以与 JNI 一起运行),但应作为最后的资源。
我找到了FileVisitor ,但它似乎不是解决我的问题的最佳方法,因为我不必访问整个文件树。我还找到了BasicFileAttributeView但它似乎有同样的问题。 This是一个相关的问题,但没有提供重要解决方案的答案。
[ 1 ]:因为这不是我唯一做的事情,所以最终像 17 岁。
编辑:代码:
internal fun workFrom(unit: ProcessUnit<D>) {
launch {
var somethingAddedToPreload = false
val file = File(unit.first)
....
//Load children folders
file.listFiles(FileFilter {
it.isDirectory
})?.forEach {
getPreloadMapMutex().withLock {
if (getPreloadMap()[it.path] == null) {
val subfiles = it.list() ?: arrayOf()
for (filename in subfiles) {
addToProcess(it.path, ProcessUnit(it.path + DIVIDER + filename, unit.second))
}
getPreloadMap()[it.path] = PreloadedFolder(subfiles.size)
if (getPreloadMap().size > PRELOADED_MAP_MAXIMUM) cleanOldEntries()
getDeleteQueue().add(it.path)
somethingAddedToPreload = somethingAddedToPreload || subfiles.isNotEmpty()
}
}
}
...
if(somethingAddedToPreload) {
work()
}
}
}
private fun addToProcess(path: String, unit: ProcessUnit<D>) {
val f: () -> Pair<String, FetcherFunction<D>> = { load(path, unit) }
preloadList.add(f)
}
private suspend fun work() {
preloadListMutex.withLock {
preloadList.forEach {
launch {
val (path, data) = it.invoke()
if (FilePreloader.DEBUG) {
Log.d("FilePreloader.Processor", "Loading from $path: $data")
}
val list = getPreloadMap()[path]
?: throw IllegalStateException("A list has been deleted before elements were added. We are VERY out of memory!")
list.add(data)
}
}
preloadList.clear()
}
}
PS:我会在进行优化之前删除工作中的协程,完整代码是here .
最佳答案
您可以运行 ls -F
并通过查看最后一个字符来检查文件是否为目录的输出,目录将以 /
结尾。例如
val cmd = "ls -F ${myFile.absolutePath}"
val process = Runtime.getRuntime().exec(cmd)
val files = process.inputStream
.bufferedReader()
.use(BufferedReader::readText)
.lines()
for (fileName in files) {
val isDir = fileName.endsWith("/")
}
我在模拟器上运行了一个快速测试,有 4000 个文件和 4000 个目录,整个过程大约需要 150 毫秒。
关于android - 文件的批量元数据请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49480264/