Увеличение максимального числа дескрипторов открытых файлов в Matlab в Windows с помощью fopen - PullRequest
4 голосов
/ 23 марта 2012

У меня есть программа, которая должна содержать приблизительно 3000 дескрипторов открытых файлов в Matlab. Причина в том, что если я не держу их открытыми, мне нужно их открывать и закрывать более 100 000 раз, что означает 300 миллионов открытых операций закрытия. Учитывая, что каждый файл добавляется каждый раз, и fopen и fclose могут занимать до секунды (файлы имеют большой размер, т. Е. 100 МБ +), должно быть ясно, что эта ситуация недопустима.

Я знаю, что ограничение Windows для дескрипторов файлов установлено на 10000, но Matlab отказывается открывать более 512 файлов с помощью fopen. Я не могу понять, как заставить его увеличить это число.

Кто-нибудь знает, как изменить лимит 512? Где это определено? Это вообще связано с Matlab?

Ответы [ 2 ]

6 голосов
/ 24 марта 2012

FWIW, ниже приведен фрагмент кода для воспроизведения этой проблемы:

fids = zeros(1,513);
for ix = 1:length(fids)
   fids(ix) = fopen(sprintf('testfile_%03d.tmp',ix),'w');
end
fids(507:end)

(После этого основные команды, такие как «помощь», не выполняются, необходимо выполнить fclose all).

Небольшой поиск в Интернете поднимает других людей (на подчиненных форумах по вопросам и ответам) с теми же проблемами, но без простых решений (например, в этом сообщении на форуме Mathworks .)


Мой первый инстинкт, когда я сталкиваюсь с ограничениями Matlab, - это всегда обращаться к Java. Например:

streamwriters = cell(1,513);
for ix = 1:length(streamwriters)
    strName = sprintf('testfile_2_%03d.tmp',ix);
    streamwriters{ix} = java.io.FileOutputStream(strName);
end
streamwriters{513}.write(uint8('Some data to write'))

Каждый раз, когда вы делаете java-вызов из Matlab, вы платите (я думаю, несколько мс), так что вы действительно выполняете 1 000 000 записей, я бы профилировал ваш код и искал способы сбора код в памяти и выполнять меньше, более крупные пакетные записи при необходимости.

Также помните, что вам нужно закрыть их по отдельности, например,

for ix = 1:length(streamwriters)
    streamwriters{ix}.close();
end
2 голосов
/ 24 марта 2012

Разве вы не можете на самом деле просмотреть вашу программу и структурировать ее по-другому, чтобы она работала только с частичным представлением содержимого файлов в памяти?

Например, если для добавления 100 000 строк к 3000 файлам (т. Е. Даже нет необходимости иметь представление о том, что уже есть в файлах), вы можете сделать это следующим образом:

%% Main processing
function [] FullProcess()
%[        
    for block = 1:100,

        % Partial processing 
        lines = processBlock(block);

        % Save step   
        pushToFiles(block, lines);     

    end        
%]

С:

% Partial processing in memory
function [lines] = processBlock(block)
%[
    % Preallocate
    lines = cells(1000, 3000);

    % Do the processing for current block
    ...
    lines{500, 12} = 'kikou';
    ...
%]

И

%% Save partial work
function [] = pushToFiles(block, lines)
%[
    fcount = size(lines, 2);
    lcount = size(lines, 1);
    for fi = 1:fcount,

       [fid, msg] = fopen(fprintf('f%i', fi), 'a'); % Open in append mode
       if (fid < 0), error(msg); end

       for li = 1:lcount,
           fprintf(fid, lines{li, fi});
       end

       fclose(fid);

    end
%]

Это сокращает количество операций до 100 fopen / fclose (хотя на 3000 файлов, но это намного меньше, чем ожидалось ранее)

...