Search code examples
matlabfiledelete-fileparformatlabpool

Unable to delete some files after script crashes


I run a MATLAB script which generates images, saving them into a certain folder. When the code crashes, I cannot delete a few images in that folder unless I restart MATLAB.

Can I solve this problem without restart MATLAB program?

Code:

clear,clc,close all
SRC1 = 'SRC1';
SRC2 = 'SRC2';
suffix1 = '_suffix1.png';
suffix2 = '_suffix2.png';
DST = 'DST';
GT = 'GT';
FEAS = {
    SRC1;
    };
feaSuffix = {
    '_suffix.png';
    };
if ~exist(DST, 'dir')
    mkdir(DST);
end
if matlabpool('size')<=0
    matlabpool('open','local',8);
else
    disp('Already initialized');
end
files1 = dir(fullfile(SRC1, strcat('*', suffix1)));
parfor k = 1:length(files1)
    disp(k);
    name1 = files1(k).name;

    gtName = strrep(name1, suffix1, '.bmp');
    gtImg = imread(fullfile(GT, gtName));
    if ~islogical(gtImg)
        gtImg = gtImg(:,:,1) > 128;
    end
    gtArea = sum(gtImg(:));
    if gtArea == 0
        error('no ground truth in %s', gtName);
    end

    img1 = imread(fullfile(SRC1, name1));
    mae1 = CalMAE(img1, gtImg);

    name2 = strrep(name1, suffix1, suffix2);
    img2 = imread(fullfile(SRC2, name2));
    mae2 = CalMAE(img2, gtImg);

    delta = mae1 - mae2 + 1;
    preffix = sprintf('%.2f_mae1_%.2f_mae2_%.2f_', delta, mae1, mae2);

    imwrite(img1, fullfile(DST, strcat(preffix, name1)));
    imwrite(img2, fullfile(DST, strcat(preffix, name2)));
    imwrite(gtImg, fullfile(DST, strcat(preffix, gtName)));

    for n = 1:length(FEAS)
        feaImgName = strrep(name1, suffix1, feaSuffix{n});
        copyfile(fullfile(FEAS{n}, feaImgName), ...
            fullfile(DST, strcat(preffix, feaImgName)));
    end
end

Solution

  • You can tell MATLAB to close any open files with

    fclose('all');
    

    In my experience fclose applies to all opened files, not just ones opened with fopen.

    Also, since you are running a matlabpool, each worker (MATLAB.exe process) will need to release their files. To do this, I suggest creating a try-catch inside the parfor like this.

    parfor k = 1:length(files1)
        try
            % your loop content here
        catch ME
            % cleanup and terminate
            fclose('all');
            rethrow(ME);
        end
    end
    

    This way, the worker that bombs out in the loop will run fclose. Running it in the master MATLAB.exe probably will not be helpful.

    However, you can also make sure you close the matlabpool before you try to delete the files since this should release any file locks that the workers have.