I have a single flat directory with over a million files. I just wanted to take a sample of the first few files but FileNames
doesn't include a "only the first n" option, and so it took over a minute:
Is there a faster way?
Using OS shells commands seems to be much faster, although their output will need some massaging to obtain only the file names.
For instance, the following works quite well on my system (Win7-64):
Import["!dir /b /a-d C:\\Windows\\*", "Text"] // StringSplit[#, "\n"] &
This command takes 0.11s to execute; for comparison the corresponding FileNames expression (FileNames["*", "C:\\Windows\\"]
) takes 0.33s. The difference is even more pronounced with larger/deeper directories.
In the dir command above, /a-d
selects files that are not directories; /b
produces minimal output which is easier to parse. If you want to traverse subdirectories, you can use the /s
option.
Import
expression? Does that not work?
$\endgroup$
man
page for ls
.
$\endgroup$
Commented
Jun 14, 2016 at 23:54
find
to list files-not-directories. ls
will do fine for a specific extension though
$\endgroup$
Commented
Jun 15, 2016 at 7:05
-p
switch in ls
.
$\endgroup$
Commented
Jun 15, 2016 at 10:46
New function in Mathematica 11 FileSystemMap
with option MaxItems
(documentation) can be useful here.
dir = "C:\\Users\\Alexey\\Documents";
n = 10;
f = FileSystemMap[#&, dir, MaxItems -> n] // Keys;
n = 10; f = FileSystemMap[#&, dir, Infinity, MaxItems -> n] // Keys;
$\endgroup$
FileSystemMap
and FileSystemScan
are much slower than FileNames
. It's very strange.
$\endgroup$
Commented
Sep 10, 2016 at 3:15
a linux version using find
to list files and head
to take the first n
.
dir = "/path"
StringSplit[
RunProcess[
{"/bin/sh",
"-c",
"find "<>dir<>" -maxdepth 1 -type f | head -10"
},"StandardOutput"]]
note find
does not return files in any canonical order, you can sort for example,
add | sort
in front of | head
Note FileNames[][;;10]]
is a good bit faster by my testing, but I don't have a folder with a million files to test it on.