MATLAB: Import files with identical names from different directories (no error messages)

data importfor loopidentical filenamesimportsubfoldertextread

I have multiple files with the same names in different subfolders. All files are called runoff.txt. The subfolders are called results1, results2, results3 and so on, so they differ only by a consecutive number.
For the import of txt files with the same names from different subfolders, I have tried an approach to solve this issue like mentioned on:
My script looks like:
pathname = 'C:\Users\heute\results\model_standalone\';
Mdir = dir(pathname);
nbentries = size(Mdir, 1);
Mfiles = [];
for entry_i = 1:nbentries
if Mdir(entry_i).isdir == false
filename = Mdir(entry_i).name;
if filename(1) ~= '.'
[p, n, ext] = fileparts(filename);
if strcmpi(ext, '.txt')
Mfiles = strvcat(Mfiles, filename);
end
end
end
end
nbfiles = size(Mfiles, 1);
for iFile = 1:length(Mfiles);
[Date,QSfirn,QSice,QSrock,QSsnow,QSsoil,Qs]=textread(Mfiles(iFile),'%s %f %f %f %f %f %f',-1,'headerlines',1);
end
The program runs without error messages but the txt files are not imported.
For example that the folder model_standalone contains 2 subfolders with the names results1, results2 and within these folders a txt file with the name runoff.txt the following output is returned:
  • Mdir: 4×1 struct
  • Mfiles: []
  • entry_i: 1×1 double
  • i: 1X1 double
  • nbentries: 1×1 double
  • nbfiles: 1×1 double with 0
  • pathname: char_
Why aren't the individual txt files recognized?
How can you fix the problem that all txt files from the subfolders are read (perhaps in a different way)?
—–
The same question has already been asked on this page:
but without any problem-solving answer.
—-
For any helpful answer I would be deeply grateful, because this problem prevents all further data evaluation processes. (I'm using Matlab R2012a).

Best Answer

Just because something was written by someone at a university does not mean that it is well written. That code is pointlessly complicated, and has several strange "features":
  • using dir to get all directory contents, and then later using if-s to pick non-folders and filenames with .txt extension. What a pointlessly complicated piece of code: you should not learn from this. Much simpler: call dir with the correct match string, including wildcard and file extension.
  • no preallocation on the output array Mfiles.
  • uses obsolete textread, which the documentation clearly recommends against using.
In any case, that code does not actually do what you ask for: your question you state "I have multiple files with the same names in different subfolders. All files are called runoff.txt. The subfolders are called results1, results2, results3 and so on." But that page states (translated) that it gets all files from one folder. So why use that code, which is pointlessly complicated and does not do what you want anyway?
All beginners would be much better off learning MATLAB from the MATLAB documentation, rather than relying on code written by some random academic who still thinks that cell arrays are very daring, or by some teenager who uploads a youtube blog on some neat tricks that they "discovered". The documentation describes the two basic ways of processing a sequence of files or folders:
and also on this forum:
In particular this example:
"To read all files that match *.jpg with imread:"
jpegFiles = dir('*.jpg');
numfiles = length(jpegFiles);
mydata = cell(1, numfiles);
for k = 1:numfiles
mydata{k} = imread(jpegFiles(k).name);
end
You can easily adapt this to read the same file from multiple directories, perhaps something like this (untested):
F = 'name.txt'; % name of the file
D = '.'; % absolute or relative path of base directory
S = dir(fullfile(D,'results*'));
X = [S.isdir] & ~ismember({S.name},{'.','..'});
N = {S(X).name};
C = cell(size(N));
for k = 1:numel(N)
T = fullfile(D,N{k},F);
C{k} = textscan(T,...); % not textread!
end
If you have sequentially numbered files then you might also be interested in processing them in numeric order, in which case you might like to download my FEX submission natsortfiles:
and then you can use it on this line:
N = natsortfiles({S(X).name});