Невозможно удалить некоторые файлы после сбоя скрипта

Я запускаю скрипт MATLAB, который генерирует изображения, сохраняя их в определенной папке. Когда происходит сбой кода, я не могу удалить несколько изображений в этой папке, пока не перезапущу MATLAB.

Могу ли я решить эту проблему без перезапуска программы MATLAB?

Код:

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

1 ответ

Решение

Вы можете указать MATLAB закрыть все открытые файлы с помощью

fclose('all');

По моему опыту fclose применяется ко всем открытым файлам, а не только к открытым fopen,

Кроме того, так как вы работаете matlabpool каждый работник (процесс MATLAB.exe) должен освободить свои файлы. Для этого я предлагаю создать try - catch внутри parfor как это.

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

Таким образом, рабочий, который бомбит в цикле, будет работать fclose, Запуск его в мастере MATLAB.exe, вероятно, не поможет.

Тем не менее, вы также можете убедиться, что вы закрыли matlabpool прежде чем пытаться удалить файлы, так как это должно снять любые блокировки файлов, которые есть у рабочих.

Другие вопросы по тегам