copy file not working as it should

hello there, i have a code that somehow just skips the copy file line and did not move file as it should. i tried adding [ status, message, messageId] to see whats going on and it did not return anything. it goes through the other lines fine, but it didnt copy it anywhere, much less the intended file. if someone can point out what i did wrong that will be very helpful. thanks!
mainfolder2 ='/Users/sesiliamaidelin/Downloads/summer project/Copy_of_CL2 Reviewer Network'; % Subfolders contains bitmap images
nufolderpath = '/Users/sesiliamaidelin/Downloads/summer project/nufolder'; % Define the path name of nufolder
filesAndFolders2 = dir([mainfolder2 '/**']); % Get all subfolder and files names
alllist2={filesAndFolders2.name}; % Convert to cell
bmpidx = cellfun(@(x) contains(x,'.bmp'),alllist2); % Index to extract dicom files only
bmplist = alllist2(bmpidx) % List of dicom files only
bmppath = {filesAndFolders2(bmpidx).folder}; % Extract the path of each dicom files
%%
for jj = 1 : numel(dcmlist)
[filepath, name, ext]= fileparts(dcmlist(jj));
ptt= digitsPattern + regexprep( dcmlist{jj},'.dcm$',' ')+'_';
for kk = 1 :numel(bmplist)
matchedIdx = contains(bmplist(kk), ptt)
if matchedIdx == true
movefile(fullfile(bmppath(kk),bmplist(kk)),fullfile( nufolderpath, name))
else
fprintf('file %s does not have a matching dicom file\n ', bmplist{kk});
end
end
end

2 Comments

What is your value of matchedIdx? Is it ever true?
when the folders with the corresponding name exist, it doesn't return a 1 on the command line, but the ones that doesn't exist return a 0 in the command line, so i assumed that when it didnt return a 0 that it returned true.

Sign in to comment.

 Accepted Answer

for jj = 1 : numel(dcmlist)
we do not know what datatype dcmlist is yet
[filepath, name, ext]= fileparts(dcmlist(jj));
dcmlist is indexed with () indexing, and the result is something that it is expected fileparts() will work on. Taking into account that jj is a scalar index, the implication is that dcmlist(jj) is either a string scalar or a scalar cell of character vector
If dcmlist(jj) is s string scalar, then the outputs of fileparts will each be string scalars. If dcmlist(jj) is a cell array of character vector, then taking into account that jj is a scalar index, the outputs will be character vectors. If jj were a non-scalar index with dcmlist(jj) then being a non-scalar cell of character vectors, then the output would be cell arrays of character vectors.
ptt= digitsPattern + regexprep( dcmlist{jj},'.dcm$',' ')+'_';
We demonstrated above that dcmlist must be either a string array or a cell array of character vector. Either way, with jj being scalar, using {jj} indexing is going to give back a character vector. So you are passing a character vector into regexprep(), and the result will then be a character vector. The transformation you do in the regexprep() is to replace any character, followed by 'dcm' at the end of the string, with a single blank. The '.' in '.dcm' will match any character, including period, not just period specifically. A little sloppy but probably good enough.
The pattern you build into ptt will match at least one digit in a row, followed by the name of the file with '.dcm' changed to a blank, followed by underscore. The blank here needs to be emphasized: you definitely have ' ' as the parameter rather than '' so you are changing '.dcm' to blank, not just deleting the '.dcm'
matchedIdx = contains(bmplist(kk), ptt)
I really have to wonder whether bmplist() contains blanks.
alllist2={filesAndFolders2.name}; % Convert to cell
alllist2 is a cell array of character vectors
bmpidx = cellfun(@(x) contains(x,'.bmp'),alllist2); % Index to extract dicom files only
bmpidx is a logical vector
bmplist = alllist2(bmpidx) % List of dicom files only
logical vector, () indexing into a cell array of character vectors, so bmplist is a cell array of character vectors.
matchedIdx = contains(bmplist(kk), ptt)
contains() is happy to work on a scalar cell array of character vector, and will return a logical scalar.
movefile(fullfile(bmppath(kk),bmplist(kk)),fullfile( nufolderpath, name))
We established that bmplist is a cell array of character vectors. bmppath() is as well, and () indexing into a cell array of character vectors returns a cell array of character vectors. What datatype does fullfile() return when passed in cell arrays of character vectors? Answer: it returns a cell array of character vectors.
Thus, if you got here at all (if that blank really is part of the name, which I doubt), then you would be executing movefile() with the first parameter being a cell array of character vector. However, the first parameter to movefile() must be a character vector or string scalar, never a cell array of character vectors, so movefile() would fail if the code got to here.

1 Comment

okay, wow thank you so much. i'm a new in matlab so i havent gotten my head around all this, but reading this helps so much. thank you for your super thorough answer!!

Sign in to comment.

More Answers (1)

Use the debugger to find out, what's going on:
for kk = 1 :numel(bmplist)
if contains(bmplist{kk}, ptt)
sourceFile = fullfile(bmppath{kk}, bmplist{kk});
destFile = fullfile(nufolderpath, name);
[succ, msg] = movefile(sourceFile, destFile);
if ~isfile(destFile)
error('File not copied?! %s -> %s', sourceFile, destFile);
end
else
fprintf('file %s does not have a matching dicom file\n', bmplist{kk});
end
end
Now set a breakpoint in the IF block and step through the code line by line. Is MOVEFILE really reached?
Such lines a fragile:
ptt= digitsPattern + regexprep( dcmlist{jj},'.dcm$',' ')+'_';
Adding CHARs lead to unexpected results, if the former argument is not a string:
'A' + '_'
% 160, no 'A_'

11 Comments

hello, thank you for your comment! i tried running it w breakpoints and it did not enter the if statement. does that mean the ptt is broken? and do you have any suggestion on anything i can replace it with? thank you!
This means, that contains(bmplist{kk}, ptt) is not true. What is ptt?
ptt is the part of the name of the file that i want to match with other files, for example ptt = 00072 and the file i want to match it with (bmplist{kk}) is 2016051200072.bmp
I would point out that 2016051200072.bmp does not contain any blanks. Your ppt would not be 00072 : it would be "one or more digits" followed by something extracted from dcmlist with .dcm changed to blank, followed by underscore ... and 2016051200072.bmp does not have blanks and does not have underscore.
oh sorry, the name is 2016051200072._Frame**.bmp. i changed the ppt part into
ptt= digitsPattern + regexprep( dcmlist{jj},'.dcm$'," ")+'_';
but it's still not moving the file. should i add Frame and the wildcard for the numbers then?
for kk = 1 :numel(bmplist)
matchedIdx = contains(bmplist(kk), ptt)
if matchedIdx == true
copyfile(fullfile(bmppath{jj},bmplist{jj}),fullfile( nufolderpath, name,'reviewer network'))
else
fprintf('file %s does not have a matching dicom file\n ', bmplist{kk});
end
end
this is the full for loop
I am confused about exactly what would be in dcmlist and exactly what filenames in bmplist need to be matched.
Would dcmlist contain '00072' and you need to move all DATE '00072._Frame' <something> '.bmp' files ?
Or is the dcmlist input by date like 20160512 and you need to move all files that start with that? Or something else?
yes! the first one is correct. so i need to copy the files from bmppath with names like DATE0002_Frame1.bmp until DATE00002_Frame32.bmp for example into a folder named EEDN inside the folder '00002'. i have attached a picture of how the folders look like. how can I make the filename matching work and move it into the subfolders of the 00002?
the bmplist and dcmlist are both cells with chars inside it. the dcmlist was actually another list of files that contained dicom files, which i already successfully moved into a folder named after its names ( folder 0002 contains 0002.dcm and the folders EEDN, UDDN and Reviewer. those three folders are where i am trying to move the files in bmplist to, based on matching the DATE0002_Frame**.bmp with the folder name 0002. a commenter answered that the line i used to match the file names are fragile so i changed it to strings or tried accessing the inside using () instead of the original {} but the matchedIdx does not display 1 when they come across a matching folder,but only displays when it returns a false (0) and it does not move the matching files either.
You know how long the DATE portion is, you know how long the folder name portion is: instead of doing pattern matching, just extract the relevant portion of the name and do the comparison.
oh right i was too fixated on the previous method i didnt think of that. Thank you! I changed the codes to this :
for kk = 1 :numel(bmplist)
bmpdcm = bmplist{kk};
bmpdcm = bmpdcm(9:16);
if bmpdcm == name
movefile(fullfile(bmppath{kk},bmplist{kk}),fullfile(nufolderpath,name,'reviewer network'))
fprintf('file %s does not have a matching dicom file\n ', bmplist{kk});
end
end
but the movefile still doesn't work.. I'm sorry for asking so many questions
Asking many question about Matlab is the purpose of this forum. So your are welcome.
It is still not clear, what "doesn't work" means. Please replace:
movefile(fullfile(bmppath{kk},bmplist{kk}),fullfile(nufolderpath,name,'reviewer network'))
by:
sourceFile = fullfile(bmppath{kk},bmplist{kk});
destFolder = fullfile(nufolderpath,name,'reviewer network');
[status, msg] = movefile(sourceFile, destFolder);
if status ~= 1
error('Cannot copy file %s to %s: %s', sourceFile, destFile, msg);
end
Maybe the destination folder is write protected? Under Windows this does not mean, that you cannot write into this folder... (I hate it). Then:
[status, msg] = movefile(sourceFile, destFolder, 'f');
Please run this and explain exactly, what you observe. I guess, that the copy works as wanted, but you expect it to appear on another location.

Sign in to comment.

Products

Release

R2021a

Community Treasure Hunt

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

Start Hunting!