几天来,我一直在寻找一个有效的错误解决方案

错误:EMFILE,打开的文件太多

似乎很多人都有同样的问题。通常的答案是增加文件描述符的数量。所以,我试过了:

sysctl -w kern.maxfiles=20480

缺省值为10240。在我看来,这有点奇怪,因为我在目录中处理的文件数量低于10240。更奇怪的是,在增加了文件描述符的数量之后,我仍然收到相同的错误。

第二个问题:

经过多次搜索,我找到了一个解决“打开文件太多”问题的方法:

var requestBatches = {};
function batchingReadFile(filename, callback) {
  // First check to see if there is already a batch
  if (requestBatches.hasOwnProperty(filename)) {
    requestBatches[filename].push(callback);
    return;
  }

  // Otherwise start a new one and make a real request
  var batch = requestBatches[filename] = [callback];
  FS.readFile(filename, onRealRead);
  
  // Flush out the batch on complete
  function onRealRead() {
    delete requestBatches[filename];
    for (var i = 0, l = batch.length; i < l; i++) {
      batch[i].apply(null, arguments);
    }
  }
}

function printFile(file){
    console.log(file);
}

dir = "/Users/xaver/Downloads/xaver/xxx/xxx/"

var files = fs.readdirSync(dir);

for (i in files){
    filename = dir + files[i];
    console.log(filename);
    batchingReadFile(filename, printFile);

不幸的是,我仍然收到相同的错误。 这段代码有什么问题?


当前回答

对于同一个问题,我做了上面提到的所有事情,但都不起作用。我试了下,它工作100%。简单的配置更改。

选项1:设置限制(大多数情况下都不起作用)

user@ubuntu:~$ ulimit -n 65535

检查电流限制

user@ubuntu:~$ ulimit -n
1024

选项2:将可用限制增加到例如65535

user@ubuntu:~$ sudo nano /etc/sysctl.conf

添加下面的行

fs.file-max = 65535

运行此命令以刷新新的配置

user@ubuntu:~$ sudo sysctl -p

编辑以下文件

user@ubuntu:~$ sudo vim /etc/security/limits.conf

向它添加以下行

root soft     nproc          65535    
root hard     nproc          65535   
root soft     nofile         65535   
root hard     nofile         65535

编辑以下文件

user@ubuntu:~$ sudo vim /etc/pam.d/common-session

把这一行加进去

session required pam_limits.so

注销并登录并尝试以下命令

user@ubuntu:~$ ulimit -n
65535

选项3:只添加这一行

DefaultLimitNOFILE=65535

到 /etc/systemd/system.conf 和 /etc/systemd/user.conf

其他回答

我有这个问题,我通过运行npm更新解决了它,它工作了。

在某些情况下,可能需要删除node_modules rm -rf node_modules/

请注意,您不必将这个问题过于复杂化,再试一次就可以了。

import { promises as fs } from "fs";

const filepaths = [];
const errors = [];

function process_file(content: string) {
    // logic here
}

await Promise.all(
    filepaths.map(function read_each(filepath) {
        return fs
            .readFile(filepath, "utf8")
            .then(process_file)
            .catch(function (error) {
                if (error.code === "EMFILE") return read_each(filepath);
                else errors.push({ file: filepath, error });
            });
    }),
);

在Windows上,似乎没有ulimit命令来增加打开文件的数量。在graceful-fs中,它维护一个队列来运行I/O操作,例如:读/写文件。

然而,fs。readFile, fs。writeFile是基于fs的。打开,因此您需要手动打开/关闭文件来解决此错误。

import fs from 'fs/promises';

const fd = await fs.open('path-to-file', 'r');

await fd.readFile('utf-8'); // <== read through file handle
await fd.close();           // <== manually close it

我不确定这是否对任何人都有帮助,我开始做一个有很多依赖关系的大项目,这让我犯了同样的错误。我的同事建议我使用brew安装watchman,这为我解决了这个问题。

brew update
brew install watchman

2019年6月26日编辑: Github链接到watchman

我安装了守望者,改变限制等,它不工作在Gulp。

不过,重新启动iterm2实际上有所帮助。