这个Kotlin FileFilter有什么问题?

时间:2018-09-29 03:03:20

标签: android lambda kotlin

我的Kotlin Android应用程序中具有以下FileFilter:

fileArray = fileDirectory.listFiles { file, filename ->
  file.length() > 0 && filename.matches(fileMatcherRegex)
}

它可以在文件名匹配器上正确过滤,但不会过滤出长度为0的文件。稍后,我遍历fileArray并记录每个文件的长度,我看到长度为0。

奇怪的是,如果我将file.length() > 0更改为file.length() > 999999999999,它将过滤掉 all 个文件,因此正在测试过滤器的length()元素。我所理解的只是没有产生结果。

我在做什么错了?

我仍然对Kotlin lambdas有所了解,所以我猜我的错误与此有关。

预先感谢

约翰

1 个答案:

答案 0 :(得分:4)

方法listFiles期望一个带有两个参数的lambda,该参数基于FilenameFilter接口上此方法中的SAM conversion

/**
 * Tests if a specified file should be included in a file list.
 *
 * @param   dir    the directory in which the file was found.
 * @param   name   the name of the file.
 * @return  <code>true</code> if and only if the name should be
 * included in the file list; <code>false</code> otherwise.
 */
boolean accept(File dir, String name);

第一个参数是包含文件的DIRECTORY,而不是文件本身。只有第二个参数代表目录中的文件。因此,您的file.length()正在检查fileDirectory.length(),而不是文件的长度。

实际上,您的原始代码读为:

val fileArray = fileDirectory.listFiles { directory, filename ->
  directory.length() > 0 && filename.matches(fileMatcherRegex)
}

现在您可以看到它是不正确的逻辑。

如果您对lambda使用单个参数,那么您将基于FileFilter接口的SAM conversion指定一个参数,即:

/**
 * Tests whether or not the specified abstract pathname should be
 * included in a pathname list.
 *
 * @param  pathname  The abstract pathname to be tested
 * @return  <code>true</code> if and only if <code>pathname</code>
 *          should be included
 */
boolean accept(File pathname);

这是正确的,您在这里询问有关文件而不是包含目录的问题。您的代码应为:

val fileArray = fileDirectory.listFiles { file ->
  file.length() > 0 && file.name.matches(fileMatcherRegex) 
}