【问题标题】:Increasing maximum number of open file descriptors in Matlab in Windows using fopen使用 fopen 在 Windows 中增加 Matlab 中打开文件描述符的最大数量
【发布时间】:2012-03-23 19:23:08
【问题描述】:

我有一个程序需要在 Matlab 中保存大约 3000 个打开的文件描述符。 这样做的原因是,如果我不让它们保持打开状态,我需要打开和关闭它们 超过 100 000 次,这意味着 3 亿次打开关闭操作。考虑到每个文件每次都附加,并且 fopen 和 fclose 可能需要一秒钟以上(文件很大,即 100mb+),应该清楚这种情况是不可接受的。

我知道文件句柄的 Windows 限制设置为 10000,但 Matlab 拒绝使用 fopen 打开超过 512 个文件。我不知道如何强制它增加这个数字。

有人知道如何更改 512 限制吗?它在哪里定义? 它甚至与Matlab相关吗?

【问题讨论】:

    标签: file matlab fopen


    【解决方案1】:

    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)。

    一点点网络搜索就会发现其他人(在劣质问答论坛上)有同样的问题,但没有简单的解决方案(例如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
    

    【讨论】:

      【解决方案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 个文件,但这远低于之前的预期)

      【讨论】:

      • 顺便说一句,您真的需要将数据分布在 3000 个文件中吗?从数据库/二进制文件中工作不是更有效吗……好吧,也许是过度解释或这种重构不适合当前上下文...
      • 我需要生成单独的文件以在并行程序中使用,因此生成 3000 个文件是目前整个程序的设计方式。我以类似于您描述的方式解决了它,但我只是以 500 个文件为一组编写。
      • 很高兴看到您已经能够重构事物。关于原始问题,这里有一些有趣的link
      猜你喜欢
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多