我有一个程序需要在Matlab中保存大约3000个打开的文件描述符。 原因是如果我不打开它们,我需要打开和关闭它们 超过10万次,这意味着3亿次开放式近距离操作。考虑到每个文件都附加到每个文件,并且fopen和fclose每个文件都需要花费一秒以上(文件很大,即100mb +),应该很清楚这种情况是不可接受的。
我知道文件句柄的Windows限制设置为10000,但Matlab拒绝使用fopen打开超过512个文件。我无法弄清楚如何强迫它增加这个数字。
有人知道如何更改512限制吗?它在哪里定义? 它甚至与Matlab有关吗?
答案 0 :(得分:6)
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
)。
一些网络搜索让其他人(在劣质Q& A论坛上)遇到同样的问题,但没有简单的解决方案(例如this Mathworks forum post。)
当我遇到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'))
每次从Matlab内部进行java调用都会产生一些成本(我想几毫秒),所以你真正做了1,000,000次写入,我会分析你的代码,并寻找收集代码的方法代码在内存中,并在需要时执行更少,更大的批量写入。
还要记住,你需要单独关闭它们,例如
for ix = 1:length(streamwriters)
streamwriters{ix}.close();
end
答案 1 :(得分:2)
难道你不能真正检查你的程序并以不同的方式构造它,以便只从文件内容的部分内存表示中工作吗?
例如,如果要将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个文件,但这远远低于之前的预期)