如何在Matlab中使用java.nio?

Luc*_*cas 5 java directory io matlab nio

我的目标是检查网络上的文件夹中是否找到具有特定(名称的一部分)的文件,同时考虑到其下面的所有文件夹。为此,我需要一种方法来有效获取给定文件夹中及其下的所有文件和文件夹的列表。我的递归函数在本地驱动器上每秒执行约 2500 个项目,但在网络驱动器上每秒仅执行几个项目。我需要更快的东西。

\n\n

核心问题是:获取文件夹中的项目列表(包括属性 isDirectory 或类似属性)的最快方法是什么?

\n\n

我寄希望于java.nio的walkFileTree功能,但我无法使用它。(版本:8.4.0.150421 (R2014b),采用 Java 1.7.0_11-b21,采用 Oracle Corporation Java HotSpot\xe2\x84\xa2 64 位服务器 VM 混合模式)

\n\n

当前问题:我无法使用 java.nio 的任何功能

\n\n

java.io 可以工作,例如创建一个文件对象:

\n\n
jFile = java.io.File('C:\\')  \n% then use jFile.list or jFile.isDirectory or jFile.toPath, it all works!\n
Run Code Online (Sandbox Code Playgroud)\n\n

天真地调用 nio 失败:

\n\n
java.nio.file.Files('C:\\') \n% -> No constructor 'java.nio.file.Files' with matching signature found.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我意识到 java.nio.file 的工作方式有点不同,要使用 Files 中的方法,需要一个路径,可以使用 java.nio.file.Path.get 构造该路径。这东西吃一根绳子。但这也失败了:

\n\n
java.nio.file.Paths.get('C:\\')  % -> No method 'get' with matching signature found for class 'java.nio.file.Paths'.\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而方法是存在的:

\n\n
methods java.nio.file.Paths \n% ->  Methods for class java.nio.file.Paths: \nequals     getClass   notify     toString   \nget        hashCode   notifyAll  wait  \n
Run Code Online (Sandbox Code Playgroud)\n\n

那么这里出了什么问题呢?我不允许输入 matlab 字符串?我应该使用 Java 字符串吗?这也失败了:

\n\n
jString = java.lang.String('C:\\');\njava.nio.file.Paths.get(jString)  \n% -> No method 'get' with matching signature found for class 'java.nio.file.Paths'. \n
Run Code Online (Sandbox Code Playgroud)\n\n

Oracle 的解决方法是在 java.io 中创建路径,但将其提供给 java.nio 也会失败。

\n\n
path = java.io.File('C:\\').toPath;\njava.nio.file.Files.isDirectory(path) \n% -> No method 'isDirectory' with matching signature found for class 'java.nio.file.Files'.\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以我什至没有更接近尝试 walkFileTree。我无法让 java.nio 在 Matlab 中执行任何操作。

\n\n

帮助:那么有人知道如何调用 java.nio.file 函数或回答我的核心问题吗?

\n\n

ps:到目前为止,没有 java.nio 的简单方法的示例,示例不包括递归部分,但显示了可怕的性能

\n\n

策略1:递归使用Matlab的'dir'函数。这是一个很好的函数,因为它还提供了属性,但它有点慢。在我的起始网络文件夹(包含 150 个文件/文件夹,路径存储为字符串 Sdir)中,以下命令需要 34.088842 秒:

\n\n
tic;d=dir(Sdir);toc\n
Run Code Online (Sandbox Code Playgroud)\n\n

策略2:使用java.io.File来加快速度,这几乎没有帮助,因为isDirectory需要调用..对项目名称使用启发式太危险了,我被迫使用其中带有点的文件夹。同一目录中的示例,31.315587 秒:

\n\n
tic;jFiles = java.io.File(Sdir).listFiles;\nLCVdir = arrayfun(@isDirectory, jFiles, 'UniformOutput',0);\ntoc\n
Run Code Online (Sandbox Code Playgroud)\n

And*_*nke 5

这些java.nio.file方法具有可变签名。看起来 Matlab 无法进行使它们透明工作所需的自动装箱,因此您需要使用参数的数组形式来调用它们。

的签名java.nio.file.Paths.getget(String first, String... more). 这相当于get(String first, String[] more).

>> java.nio.file.Paths.get('C:\', javaArray('java.lang.String', 0))
ans =
C:\
>> class(ans)
ans =
sun.nio.fs.UnixPath
Run Code Online (Sandbox Code Playgroud)

同样, 的签名java.nio.file.Files.isDirectoryisDirectory(Path path, LinkOption... options),因此您需要提供options参数。

>> p = java.nio.file.Paths.get('/usr/local', javaArray('java.lang.String', 0));
>> java.nio.file.Files.isDirectory(p, javaArray('java.nio.file.LinkOption', 0))
ans =
  logical
   1
>> 
Run Code Online (Sandbox Code Playgroud)

顺便说一句,该Files.walkFileTree方法将要求您实现一个自定义java.nio.file.FileVisitor子类,您需要在 Java 中而不是普通的 Matlab 中执行此操作。

另外,由于您位于网络驱动器上,因此网络文件 I/O 实际上可能是您的瓶颈,因此不要对 Java NIO 解决方案的速度抱有太高的希望。为了使速度变得非常快,遍历需要在能够快速访问文件系统数据的机器上运行,或者更好的是,在可以对其进行索引以进行高效搜索的机器上运行。