简体   繁体   中英

How to use java.nio in Matlab?

My goal is to check if a file with a particular (part of the name) is found in a folder on the network, also taking into account all folders below it. To do so I need a way to efficiently get a list of all files and folders in and below a given folder. My recursive function does ~2500 items/s on a local drive, but only several/sec on a network drive. I need something faster.

The core question is: what is the fastest way to get a list of items in a folder including the attribute isDirectory or something similar?

I put my hope on the walkFileTree functionality of java.nio, but I am unable to use it. (version: 8.4.0.150421 (R2014b) with Java 1.7.0_11-b21 with Oracle Corporation Java HotSpot™ 64-Bit Server VM mixed mode)

Current problem: I am unable to use any functionality from java.nio

java.io works, eg create a file object:

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

Naively calling nio fails:

java.nio.file.Files('C:\') 
% -> No constructor 'java.nio.file.Files' with matching signature found.

I realize java.nio.file works a bit differently, to use the methods in Files a path is needed, which can be constructed with java.nio.file.Path.get. This thing eats a string. But this also fails:

java.nio.file.Paths.get('C:\')  % -> No method 'get' with matching signature found for class 'java.nio.file.Paths'.

However the method exists:

methods java.nio.file.Paths 
% ->  Methods for class java.nio.file.Paths: 
equals     getClass   notify     toString   
get        hashCode   notifyAll  wait  

So what is going wrong here? I am not allowed to feed a matlab string? Should I use a Java string? This too fails:

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

An oracle workaround is to create the path in java.io, but feeding that to java.nio also fails..

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

So I am not getting any closer to even trying the walkFileTree. I can not get java.nio to do anything in Matlab.

Help: so does anybody have any idea on how to call the java.nio.file functions or answer my core question?

ps: examples of straightforward methods so far without java.nio, examples do no include the recursive part but show the horrible performance

strategy 1: recursively use Matlab's 'dir' function. It is a nice function, as it also gives attributes, but it is a bit slow. In my starting network folder (contains 150 files/folders, path stored as string Sdir) the following command takes 34.088842 sec :

tic;d=dir(Sdir);toc

strategy 2: use java.io.File to speed things up, this hardly helps, because isDirectory needs calling.. Using a heuristic on the names of the items is too dangerous, I am forced to use folders with dots in them. Example in same dir, 31.315587 sec:

tic;jFiles = java.io.File(Sdir).listFiles;
LCVdir = arrayfun(@isDirectory, jFiles, 'UniformOutput',0);
toc

Those java.nio.file methods have variadic signatures . Looks like Matlab is unable to do the auto-boxing needed to make them work transparently, so you will need to call them with the array form of their arguments.

The signature for java.nio.file.Paths.get is get(String first, String... more) . This is equivalent to 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

Similarly, the signature for java.nio.file.Files.isDirectory is isDirectory(Path path, LinkOption... options) , so you need to supply the options argument.

>> 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
>> 

BTW, the Files.walkFileTree method will require you to implement a custom java.nio.file.FileVisitor subclass, which you will need to do in Java, not plain Matlab.

Also, since you're on a network drive, the network file I/O might actually be your bottleneck here, so don't get your hopes too high for the Java NIO solution to be much faster. To make this really fast, the traversal needs to be run on a machine that has fast access to the filesystem data, or even better, something that has indexed it for efficient searching.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM