Why dir function is creating additional files while creating a structure? how to ignore it?

17 views (last 30 days)
Im trying to make a loop that reading all the files in a choosen folder, I use the dir function to make list of the names of the files and to iterate this list:
files = dir('folder');
for k =1:length(files)
I = imread(files(k).name);
But there is always an error:
Error using imread (line 347)
Cannot open file "." for reading. You might not have read permission.
When I open my structure named "files" there is 2 new rows that the dir function creates in addition to all the other files in that structure:
the first file named '.' and the second '..', those files not exist in the original folder, what to do to erase them or ignore them permanently?

Accepted Answer

Catalytic
Catalytic on 27 Mar 2019
Edited: Catalytic on 27 Mar 2019
Do a more specific search, like
files = dir('folder/*.jpg');
Or, just throw the first 2 away
files = dir('folder');
files(1:2)=[];
  2 Comments
Stephen23
Stephen23 on 27 Mar 2019
Edited: Stephen23 on 28 Mar 2019
"Or, just throw the first 2 away"
Do NOT do this. The files/folders are those returned by the OS, and the presence or specific location of . and .. is not guaranteed. This has been discussed many times on this forum. It is also easy to demonstrate: simply create some files with names starting with ! or ' (both perfectly valid characters for filenames on both Windows and Unix, and which sort before the . character), and you will see that . and .. are NOT the first names returned by dir:
>> mkdir('subdir')
>> fclose(fopen('subdir/!test.txt','wt'));
>> fclose(fopen('subdir/''test.txt','wt'));
>> fclose(fopen('subdir/_test.txt','wt'));
>> S = dir('subdir');
>> {S.name}
ans =
'!test.txt' ''test.txt' '.' '..' '_test.txt'
To write robust code, simply use setdiff or ismember to select or remove names:
>> setdiff({S.name},{'.','..'})
ans =
'!test.txt' ''test.txt' '_test.txt'
Matt J
Matt J on 28 Mar 2019
Edited: Matt J on 28 Mar 2019
Or, similar to what Stephen suggests,
Names=deblank(string(ls('folder')));
Names(Names=="." | Names=="..")=[];
for I =1:numel(Names)
I = imread(Names{i});
...
end

Sign in to comment.

More Answers (1)

Steven Lord
Steven Lord on 28 Mar 2019
If you're calling imread on the output of dir, you probably want to first check that the entry you're trying to read isn't a directory. You can do this all at once using the isdir field of the struct array returned by dir.
D = dir();
numberOfEntriesPreTrim = numel(D);
D = D(~[D.isdir]);
numberOfEntriesPostTrim = numel(D);
numberOfDirectories = numberOfEntriesPreTrim-numberOfEntriesPostTrim;
for whichfile = 1:numberOfEntriesPostTrim
fprintf('File %d is %s.\n', whichfile, D(whichfile).name)
end
fprintf('Printed %d of %d entries in pwd (%d are directories.)\n', ...
numberOfEntriesPostTrim, numberOfEntriesPreTrim, numberOfDirectories);
Note that '.' and '..' are not printed by the fprintf statement. They were trimmed because they're directories, but they still count for the last fprintf statement.
I needed to wrap D.isdir in square brackets because it creates a comma-separated list. The square brackets concatenates all the elements of that list into a vector.
As for what . and .. are, on the operating systems on which MATLAB is currently supported they are the current directory and the parent directory, respectively.

Categories

Find more on Structures in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!