MATLAB - read files from directory? - matlab

I wish to read files from a directory and iteratively perform an operation on each file. This operation does not require altering the file.
I understand that I should use a for loop for this. Thus far I have tried:
FILES = ls('path\to\folder');
for i = 1:size(FILES, 1);
STRU = pdbread(FILES{i});
end
The error returned here suggests to me, a novice, that listing a directory with ls() does not assign the contents to a data structure.
Secondly I tried creating a file containing on each line a path to a file, e.g.,
C:\Documents and Settings\My Documents\MATLAB\asd.pdb
C:\Documents and Settings\My Documents\MATLAB\asd.pdb
I then read this file using the following code:
fid = fopen('paths_to_files.txt');
FILES = textscan(fid, '%s');
FILES = FILES{1};
fclose(fid);
This code reads the file but creates a newline where a space exists in the pathway, i.e.
'C:\Documents'
'and'
'Setting\My'
'Documents\MATLAB\asd.pdb'
Ultimately, I then intended to use the for loop
for i = 1:size(FILES, 1)
PDB = pdbread(char(FILES{i}));
to read each file but pdbread() throws an error proclaiming that the file is of incorrect format or does not exist.
Is this due to the newline separation of paths when the pathway file is read in?
Any help or suggestions greatly apppreciated.
Thanks,
S :-)

First Get a list of all files matching your criteria:
( in this case pdb files in C:\My Documents\MATLAB )
matfiles = dir(fullfile('C:', 'My Documents', 'MATLAB', '*.pdb'))
Then read in a file as follows:
( Here i can vary from 1 to the number of files )
data = load(matfiles(i).name)
Repeat this until you have read all your files.
A simpler alternative if you can rename your files is as follows:-
First save the reqd. files as 1.pdb, 2.pdb, 3.pdb,... etc.
Then the code to read them iteratively in Matlab is as follows:
for i = 1:n
str = strcat('C:\My Documents\MATLAB', int2str(i),'.pdb');
data = load(matfiles(i).name);
% use our logic here
% before proceeding to the next file
end

I copy this from yahoo answers! It worked for me
% copy-paste the following into your command window or your function
% first, you have to find the folder
folder = uigetdir; % check the help for uigetdir to see how to specify a starting path, which makes your life easier
% get the names of all files. dirListing is a struct array.
dirListing = dir(folder);
% loop through the files and open. Note that dir also lists the directories, so you have to check for them.
for d = 1:length(dirListing)
if ~dirListing(1).isdir
fileName = fullfile(folder,dirListing(d).name); % use full path because the folder may not be the active path
% open your file here
fopen(fileName)
% do something
end % if-clause
end % for-loop

Related

How to rename a file inside a zip file without extracting it using Matlab commands

I have a bunch of zip folders that I have to extract and read the data (stored in a unique file). The problem is some of these folders have two files by any kind of error (instead of 1) with the same name. When I use the Matlab command "unzip", one of the files is overwrited by the other. The problem is these two files are not the same: one of them has the information I need, and the other one is almost empty. So I would like to rename these two files to file_a and file_b, extract them, and once both are extracted, keep only the larger one.
Do you know if there is any way to rename files inside a zip?
I made a function which will modify the filenames inside the zip file so they can be uncompressed seemlessly.
The function locate the file names in the zip file and change the first letter of each file it encounter with a sequence "A, B, C, D, etc ...".
function differentiateFileNames(zipFilename)
%% get the filenames contained in the zip file
filenames = getZipFileNames(zipFilename) ;
nFiles = numel(filenames) ;
%% Find the positions of the file name fields
% read the full file as a string
str = fileread(zipFilename) ;
% if all filenames are identical, we only need to search for the first name
% in our list
idx = strfind( str , filenames{1} ) ;
%% group indices by physical file
% Each filename appears twice in the zip file:
% ex for 2 files: file1 ... file2 ... file1 ...file2
idx = reshape(idx,nFiles,2)-1 ;
%% Now modify each filename
% (replace the first character of each filename)
fid = fopen(zipFilename,'r+') ;
for k=1:nFiles
char2write = uint8('A'+(k-1)) ; % will be: A, B, C, D, ect ...
fseek(fid,idx(k,1),'bof') ;
fwrite(fid,char2write,'uint8') ;
fseek(fid,idx(k,2),'bof') ;
fwrite(fid,char2write,'uint8') ;
end
fclose(fid) ;
end
function filenames = getZipFileNames(zipFilename)
try
% Create a Java file of the ZIP filename.
zipJavaFile = java.io.File(zipFilename);
% Create a Java ZipFile and validate it.
zipFile = org.apache.tools.zip.ZipFile(zipJavaFile);
% Extract the entries from the ZipFile.
entries = zipFile.getEntries;
catch exception
if ~isempty(zipFile)
zipFile.close;
end
delete(cleanUpUrl);
error(message('MATLAB:unzip:invalidZipFile', zipFilename));
end
cleanUpObject = onCleanup(#()zipFile.close);
k = 0 ;
filenames = cell('') ;
while entries.hasMoreElements
k=k+1;
filenames{k,1} = char(entries.nextElement.getName) ;
end
zipFile.close
end
Be aware that this script assumes that all the files have a similar name in the zip file. When it locate the file names position it only check versus the first file name found.
The sub function getZipFileNames is just a rip off of parts of the unzip.m, with only the necessary content to be able to read the file names contained in the zip file.
For testing:
I made a zip file containing 2 files:
New Text Document1.txt
New Text Document2.txt
I modified the file names inside the zip file with a hex editor, in order to have:
New Text Document1.txt
New Text Document1.txt
so both files have the same name in the archive. If I try to unzip that file, as you described I only get one file in output (the last file overwrite the other).
If I run differentiateFileNames(zipFilename), then unzip the file, I get 2 files in the output directory:
Aew Text Document1.txt
Bew Text Document1.txt
I know it can look a bit cryptic, but it insures the files are diferentiated. If you want, as an exercise, it wouldn't take much to extend the script to directly unzip the files, find out the largest one, delete the other, then rename the file left with the proper original name.

Loop through .fig files and group them into folders based on the file name

I have a lot of .fig files that are named like this: 20160922_01_id_32509055.fig, 20160921_02_id_53109418.fig and so on.
So I thought that I create a script that loop through all the .fig files in the folder and group(copy) them into another folder(s) based on the last number in the file name. The folder is created based on the id number. Is this possible?
I have been looking on other solutions involving looping through folders but I am totally fresh. This would make it easier for me to check the .fig files while I am learning to do other stuff in Matlab.
All is possible with MATLAB! We can use dir to get all .fig files, then use regexp to get the numeric part of each filename and then use copyfile to copy the file to it's new home. If you want to move it instead, you can use movefile instead .
% Define where the files are now and where you want them.
srcdir = '/my/input/directory';
outdir = '/my/output/directory';
% Find all .fig files in the source directory
figfiles = dir(fullfile(srcdir, '*.fig'));
figfiles = {figfiles.name};
for k = 1:numel(figfiles)
% Extract the last numeric part from the filename
numpart = regexp(figfiles{k}, '(?<=id_)\d+', 'match', 'once');
% Determine the folder we are going to put it in
destination = fullfile(outdir, numpart);
% Make sure the folder exists
if ~exist(destination, 'dir')
mkdir(destination)
end
% Copy the file there!
copyfile(fullfile(srcdir, figfiles{k}), destination)
end
Here's an example how to identify and copy the files. I'll let you do the for loop :)
>> Figs = dir('*.fig'); % I had two .fig files on my desktop
>> Basename = strsplit(Figs(1).name, '.');
>> Id = strsplit(Basename{1}, '_');
>> Id = Id{3};
>> mkdir(fullfile('./',Id));
>> copyfile(Figs(1).name, fullfile('./',Id));
Play with the commands to see what they do. It should be straightforward :)

read image permission in Matlab

I'm trying to access images in a matlab interface
my code is as follows:
global im2 im
axes(handles.axes4);
[path1, user_cance]= imgetfile();
if user_cance
msgbox(sprintf('Error'), 'Error', 'Error');
return
end
srcFiles = dir('C:\Users\User\Desktop\images test\yale faces\yalefaces\..');
% yale faces is the database folder
for i = 1 : length(srcFiles)
file_name=dir(strcat('C:\Users\User\Desktop\images test\yale faces\yalefaces'));
im2=imread(strcat('C:\Users\User\Desktop\images test\yale faces\yalefaces',file_name(i).name));
%processing of read image
end
the issue is that when I run the code, it gives the following error:
Can't open file "C:\Users\User\Desktop\images test\yale faces\yalefaces" for
reading;
you may not have read permission.
Does anyone know how to solve this issue?
When you do a directory listing (without any wildcards) you are going to get the current directory '.' and parent directory as well '..'. You can't read these like files because they are directories. You will need to filter out the directories prior to trying to read them with imread.
files = dir('C:\Users\User\Desktop\images test\yale faces\yalefaces');
% Remove directories
files = files(~[files.isdir]);
As a side note, it is very hard to tell what your code is doing, but I'm pretty sure it doesn't do what you hope.
It seems like you want to get all images within the database. If that's so, you'll want to do something like.
folder = 'C:\Users\User\Desktop\images test\yale faces\yalefaces';
% Get a list of all files in this folder
files = dir(folder);
files = files(~[files.isdir]);
for k = 1:numel(files)
% Append the folder with the filename to get the path and load
im2 = imread(fullfile(folder, files(k).name));
end
I highly discourage using strcat to construct file paths particularly because it removes trailing/leading whitespace from each input which can corrupt a filename. fullfile was designed for exactly this so please use that.

How to classify elements in a folder and its subfolder in Matlab for matching purposes

I have a folder dat that could contain n subfolders and these contain various .dat files
I need to get all the files in these subfolder stored in a data structure myarchive that contains the file_name, its subfolder_name and a object resulanalysis that is the result of a my analysis script
The purpose of this operation is to obtain file_name and subfolder_name of the entries in myarchive that matches a generic result
With this code I'm able to get all the analysis result of the files contained in the current folder and I have the matching function, but I don't know how to solve the described classification problem.
files = dir('*.dat');
for file = files'
im = load(file.name);
result=myanalyzer(im);
end
Could someone help me?
If someone has a better strategy that could meet my problem is welcome.
Thanks.
If I understand you correctly, you want to through all the subfolders, load the .dat file, run some analysis and see if the result matches a certain value. If it matches you wan to save the names of the subfolder and the file in a data structure myarchive. If that's the case, here's the code:
topfolder = '...\dat\'; % Specify the full path to the dat folder
cd(topfolder)
subfolderlist = dir;
subfolderlist = subfolderlist(3:end); % because the first two results are '.' and '..'
counter = 0;
for ii = 1:lenght(subfolderlist)
cd([topfolder,subfolderlist(ii).name])
filename = dir('*.dat');
im = load(filename); % assuming there is only one .dat file in the folder
if myanalyzer(im) == result
counter = counter + 1;
myarchive(counter).subfolder_name = subfolerlist(ii);
myarchive(counter).filename = filename;
end
end

MATLAB: Use a variable with a file extenstion to load files

I am using MATLAB
I Have 51 files in their own directory all of .out extention created by a seperate program, all numbered 0 to 50.
ie
0.out
1.out
2.out
and so on til 50.out.
I need to load each file 1 by one to do calculations upon them within a for loop. How would I do this using the count variable to load the file, if the directory is set beforehand?
i.e.
%set directiory
cd(......)
%for loop
For count = 0:50,
data = count.out *<-----this line*
.....
Many thanks!
First generate the file name with
fileName = [int2str(count) '.out'];
then open the file with
fid = fopen(fileName, 'r');
The loading phase depends on the kind of file you want to read. Assuming it is a text file you can, for example, read it line after line with
while ~feof(fid)
line = fgetl(fid);
end
or use more specialized functions (see http://www.mathworks.it/it/help/matlab/text-files.html). Before the end of the for loop you'll have to close the file by calling
fclose(fid);
Another quite nice way to do it is to use the dir function
http://www.mathworks.co.uk/help/matlab/ref/dir.html
a = dir('c:\docs*.out')
Will give you a structure containing all the info about the *.out files in the directory you point it to, (or the path). You can then loop through it bit by bit. using fopen or csvread or whatever file reading function you want to use.