File 使用fopen在Windows中增加Matlab中打开文件描述符的最大数量
我有一个程序,需要在Matlab中保存大约3000个打开的文件描述符。 这样做的原因是,如果我不让它们打开,我需要打开和关闭它们 超过10万次,意味着3亿次开闭操作。考虑到每次都会附加每个文件,并且fopen和fclose每次都可能需要一秒钟以上的时间(文件很大,即100mb+),显然这种情况是不可接受的 我知道文件句柄的Windows限制设置为10000,但Matlab拒绝使用fopen打开超过512个文件。我想不出如何强迫它增加这个数字 有人知道如何更改512限制吗?它的定义是什么?File 使用fopen在Windows中增加Matlab中打开文件描述符的最大数量,file,matlab,fopen,File,Matlab,Fopen,我有一个程序,需要在Matlab中保存大约3000个打开的文件描述符。 这样做的原因是,如果我不让它们打开,我需要打开和关闭它们 超过10万次,意味着3亿次开闭操作。考虑到每次都会附加每个文件,并且fopen和fclose每次都可能需要一秒钟以上的时间(文件很大,即100mb+),显然这种情况是不可接受的 我知道文件句柄的Windows限制设置为10000,但Matlab拒绝使用fopen打开超过512个文件。我想不出如何强迫它增加这个数字 有人知道如何更改512限制吗?它的定义是什么? 它甚至
它甚至与Matlab有关吗 FWIW,下面是一些重现此问题的代码:
fids = zeros(1,513);
for ix = 1:length(fids)
fids(ix) = fopen(sprintf('testfile_%03d.tmp',ix),'w');
end
fids(507:end)
(在此之后,“help”等基本命令失败,您需要运行fclose all
)
一点网络搜索就会发现其他人(在低级问答论坛上)也有同样的问题,但没有简单的解决方案(例如…)
当我遇到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调用都会产生成本(我认为只有几毫秒),因此如果您真的要进行1000000次写入,我会分析您的代码,并寻找在内存中收集代码的方法,如果需要,执行更少、更大的批写入
还要记住,您需要单独关闭这些,例如
for ix = 1:length(streamwriters)
streamwriters{ix}.close();
end
难道你们真的不能重新审视你们的程序并以不同的方式构建它,以便只从文件内容的部分内存表示中工作吗 例如,如果要将100000行附加到3000个文件中(即,甚至不需要对文件中已有的内容进行任何表示),则可以通过以下方式执行:
%% Main processing
function [] FullProcess()
%[
for block = 1:100,
% Partial processing
lines = processBlock(block);
% Save step
pushToFiles(block, lines);
end
%]
与:
以及:
%%保存部分工作
函数[]=推送文件(块、行)
%[
fcount=大小(行,2);
lcount=大小(行,1);
对于fi=1:fcount,
[fid,msg]=fopen(fprintf('f%i',fi),'a');%在追加模式下打开
如果(fid<0),错误(msg);结束
对于li=1:l计数,
fprintf(fid,行{li,fi});
结束
fclose(fid);
结束
%]
这样可以减少100个fopen/fclose(虽然减少了3000个文件,但这远远低于以前的预期)顺便问一下,您真的需要将数据分散到3000个文件上吗?使用数据库/二进制文件不是更有效吗。。。嗯,可能是过度解释或这样的重构不适合当前环境…我需要生成单独的文件以用于并行程序,因此生成3000个文件是整个程序当前的设计方式。我的解决方法与你描述的类似,但我只是以500个文件为一组来编写。很高兴看到你能够重构东西。关于最初的问题,这里有些有趣。
% 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
%]