如何在MATLAB中获取特定目录下的所有文件?

How to get all files under a specific directory in MATLAB?

我需要获取D:\dic下的所有文件,并循环这些文件以进一步单独处理。

matlab支持这种操作吗?

它可以在其他脚本中完成,如php、python…


更新:考虑到这篇文章已经很老了,并且我在这段时间内为自己的使用做了很多修改,我认为我应该发布一个新的版本。我最新的代码可以在MathWorks文件交换中找到:dirPlus.m。您还可以从Github获取源代码。

我做了一些改进。现在,它为您提供了预先设置完整路径或只返回文件名(从Doresoom和Oz Radiano合并而来)的选项,并将正则表达式模式应用于文件名(从Peter D合并而来)。此外,我添加了对每个文件应用验证功能的功能,允许您根据条件(而不仅仅是文件名(即文件大小、内容、创建日期等)来选择它们。

注:在较新版本的matlab(r2016b及更高版本)中,dir函数具有递归搜索功能!因此,您可以这样做来获取当前文件夹所有子文件夹中所有*.m文件的列表:

1
dirData = dir('**/*.m');

旧代码:(代表子孙后代)

下面是一个函数,它递归地搜索给定目录的所有子目录,收集它找到的所有文件名的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function fileList = getAllFiles(dirName)

  dirData = dir(dirName);      %# Get the data for the current directory
  dirIndex = [dirData.isdir];  %# Find the index for directories
  fileList = {dirData(~dirIndex).name}';  %'# Get a list of the files
  if ~isempty(fileList)
    fileList = cellfun(@(x) fullfile(dirName,x),...  %# Prepend path to files
                       fileList,'UniformOutput',false);
  end
  subDirs = {dirData(dirIndex).name};  %# Get a list of the subdirectories
  validIndex = ~ismember(subDirs,{'.','..'});  %# Find index of subdirectories
                                               %#   that are not '.' or '..'
  for iDir = find(validIndex)                  %# Loop over valid subdirectories
    nextDir = fullfile(dirName,subDirs{iDir});    %# Get the subdirectory path
    fileList = [fileList; getAllFiles(nextDir)];  %# Recursively call getAllFiles
  end

end

将上述函数保存在matlab路径的某个位置后,可以按以下方式调用它:

1
fileList = getAllFiles('D:\dic');


您正在查找dir以返回目录内容。

要循环遍历结果,只需执行以下操作:

1
2
3
4
dirlist = dir('.');
for i = 1:length(dirlist)
    dirlist(i)
end

这将提供以下格式的输出,例如:

1
2
3
4
5
name: 'my_file'
date: '01-Jan-2010 12:00:00'
bytes: 56
isdir: 0
datenum: []


我使用了这个伟大答案中提到的代码,并将其扩展为支持我在本例中需要的2个附加参数。这些参数是要筛选的文件扩展名,以及指示是否将完整路径连接到文件名的标志。

我希望它足够清楚,有人会发现它是有益的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function fileList = getAllFiles(dirName, fileExtension, appendFullPath)

  dirData = dir([dirName '/' fileExtension]);      %# Get the data for the current directory
  dirWithSubFolders = dir(dirName);
  dirIndex = [dirWithSubFolders.isdir];  %# Find the index for directories
  fileList = {dirData.name}';  %'# Get a list of the files
  if ~isempty(fileList)
    if appendFullPath
      fileList = cellfun(@(x) fullfile(dirName,x),...  %# Prepend path to files
                       fileList,'UniformOutput',false);
    end
  end
  subDirs = {dirWithSubFolders(dirIndex).name};  %# Get a list of the subdirectories
  validIndex = ~ismember(subDirs,{'.','..'});  %# Find index of subdirectories
                                               %#   that are not '.' or '..'
  for iDir = find(validIndex)                  %# Loop over valid subdirectories
    nextDir = fullfile(dirName,subDirs{iDir});    %# Get the subdirectory path
    fileList = [fileList; getAllFiles(nextDir, fileExtension, appendFullPath)];  %# Recursively call getAllFiles
  end

end

运行代码的示例:

1
fileList = getAllFiles(dirName, '*.xml', 0); %#0 is false obviously

您可以使用regexp或strcmp来消除...。或者,如果只需要目录中的文件,而不是文件夹,则可以使用isdir字段。

1
2
3
list=dir(pwd);  %get info of files/folders in current directory
isfile=~[list.isdir]; %determine index of files vs folders
filenames={list(isfile).name}; %create cell array of file names

或者合并最后两行:

1
filenames={list(~[list.isdir]).name};

目录中的文件夹列表,不包括。并且…

1
2
dirnames={list([list.isdir]).name};
dirnames=dirnames(~(strcmp('.',dirnames)|strcmp('..',dirnames)));

从现在开始,您应该能够将代码放入嵌套的for循环中,并继续搜索每个子文件夹,直到您的dirname为每个子目录返回一个空单元格为止。


这个答案不能直接回答问题,但可能是一个很好的解决方案。

我支持gnovice的解决方案,但希望提供另一种解决方案:使用操作系统的与系统相关的命令:

1
2
3
4
5
6
7
8
9
10
tic
asdfList = getAllFiles('../TIMIT_FULL/train');
toc
% Elapsed time is 19.066170 seconds.

tic
[status,cmdout] = system('find ../TIMIT_FULL/train/ -iname"*.wav"');
C = strsplit(strtrim(cmdout));
toc
% Elapsed time is 0.603163 seconds.

积极的:

  • 非常快(在我的例子中,Linux上有18000个文件的数据库)。
  • 您可以使用经过良好测试的解决方案。
  • 您不需要学习或重新创建新的语法来选择,即*.wav文件。

否定的:

  • 你不是系统独立的。
  • 您依赖于一个可能难以解析的字符串。

我不知道这个的单函数方法,但是您可以使用genpath来递归一个子目录列表。此列表以分号分隔的目录字符串形式返回,因此必须使用strread将其分隔,即。

dirlist = strread(genpath('/path/of/directory'),'%s','delimiter',';')

如果不想包含给定的目录,请删除dirlist的第一个条目,即dirlist(1)=[];,因为它始终是第一个条目。

然后用循环的dir获取每个目录中的文件列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
filenamelist=[];
for d=1:length(dirlist)
    % keep only filenames
    filelist=dir(dirlist{d});
    filelist={filelist.name};

    % remove '.' and '..' entries
    filelist([strmatch('.',filelist,'exact');strmatch('..',filelist,'exact'))=[];
    % or to ignore all hidden files, use filelist(strmatch('.',filelist))=[];

    % prepend directory name to each filename entry, separated by filesep*
    for f=1:length(filelist)
        filelist{f}=[dirlist{d} filesep filelist{f}];
    end

    filenamelist=[filenamelist filelist];
end

filesep返回运行matlab平台的目录分隔符。

这将为您提供单元数组文件名列表中具有完整路径的文件名列表。不是最干净的溶液,我知道。


这是一个获取文件名的简便函数,在根文件夹中使用指定的格式(通常是.mat)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    function filenames = getFilenames(rootDir, format)
        % Get filenames with specified `format` in given `foler`
        %
        % Parameters
        % ----------
        % - rootDir: char vector
        %   Target folder
        % - format: char vector = 'mat'
        %   File foramt

        % default values
        if ~exist('format', 'var')
            format = 'mat';
        end

        format = ['*.', format];
        filenames = dir(fullfile(rootDir, format));
        filenames = arrayfun(...
            @(x) fullfile(x.folder, x.name), ...
            filenames, ...
            'UniformOutput', false ...
        );
    end

在您的案例中,您可以使用以下代码段:)

1
2
3
4
5
filenames = getFilenames('D:/dic/**');
for i = 1:numel(filenames)
    filename = filenames{i};
    % do your job!
end

只需稍作修改,但几乎类似的方法即可获得每个子文件夹的完整文件路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
dataFolderPath = 'UCR_TS_Archive_2015/';

dirData = dir(dataFolderPath);      %# Get the data for the current directory
dirIndex = [dirData.isdir];  %# Find the index for directories
fileList = {dirData(~dirIndex).name}';  %'# Get a list of the files
if ~isempty(fileList)
    fileList = cellfun(@(x) fullfile(dataFolderPath,x),...  %# Prepend path to files
        fileList,'UniformOutput',false);
end
subDirs = {dirData(dirIndex).name};  %# Get a list of the subdirectories
validIndex = ~ismember(subDirs,{'.','..'});  %# Find index of subdirectories
%#   that are not '.' or '..'
for iDir = find(validIndex)                  %# Loop over valid subdirectories
    nextDir = fullfile(dataFolderPath,subDirs{iDir});    %# Get the subdirectory path
    getAllFiles = dir(nextDir);
    for k = 1:1:size(getAllFiles,1)
        validFileIndex = ~ismember(getAllFiles(k,1).name,{'.','..'});
        if(validFileIndex)
            filePathComplete = fullfile(nextDir,getAllFiles(k,1).name);
            fprintf('The Complete File Path: %s
', filePathComplete);
        end
    end
end