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

错误: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);

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


当前回答

以下是我的观点:考虑到CSV文件只是几行文本,我已经流化了数据(字符串)以避免这个问题。

在我的用例中最简单的解决方案。

它可以与优雅fs或标准fs一起使用。请注意,在创建文件时,文件中不会有头文件。

// import graceful-fs or normal fs
const fs = require("graceful-fs"); // or use: const fs = require("fs") 

// Create output file and set it up to receive streamed data
// Flag is to say "append" so that data can be recursively added to the same file 
let fakeCSV = fs.createWriteStream("./output/document.csv", {
  flags: "a",
});

和数据,需要流到文件我已经这样做了

// create custom streamer that can be invoked when needed
const customStreamer = (dataToWrite) => {
  fakeCSV.write(dataToWrite + "\n");
};

注意,dataToWrite只是一个带有自定义分隔符“;”或“,”的字符串。 即。

const dataToWrite = "batman" + ";" + "superman"
customStreamer(dataToWrite);

这将向文件写入“batman;superman”。


请注意,在这个示例中没有错误捕获或其他任何东西。 文档:https://nodejs.org/api/fs.html # fs_fs_createwritestream_path_options

其他回答

以下是我的观点:考虑到CSV文件只是几行文本,我已经流化了数据(字符串)以避免这个问题。

在我的用例中最简单的解决方案。

它可以与优雅fs或标准fs一起使用。请注意,在创建文件时,文件中不会有头文件。

// import graceful-fs or normal fs
const fs = require("graceful-fs"); // or use: const fs = require("fs") 

// Create output file and set it up to receive streamed data
// Flag is to say "append" so that data can be recursively added to the same file 
let fakeCSV = fs.createWriteStream("./output/document.csv", {
  flags: "a",
});

和数据,需要流到文件我已经这样做了

// create custom streamer that can be invoked when needed
const customStreamer = (dataToWrite) => {
  fakeCSV.write(dataToWrite + "\n");
};

注意,dataToWrite只是一个带有自定义分隔符“;”或“,”的字符串。 即。

const dataToWrite = "batman" + ";" + "superman"
customStreamer(dataToWrite);

这将向文件写入“batman;superman”。


请注意,在这个示例中没有错误捕获或其他任何东西。 文档:https://nodejs.org/api/fs.html # fs_fs_createwritestream_path_options

这可能会解决你的问题,如果你正在努力部署一个用Visual Studio模板创建的React解决方案(并有一个web.config)。在Azure发布管道中,选择模板时,使用:

Azure应用程序服务部署

而不是:

将Node.js应用部署到Azure应用服务

这对我很管用!

对于同一个问题,我做了上面提到的所有事情,但都不起作用。我试了下,它工作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

以@blak3r的回答为基础,以下是我使用的一些速记,以防它有助于其他诊断:

如果你试图调试一个正在耗尽文件描述符的node .js脚本,这里有一行给你问题节点进程使用的lsof的输出:

openFiles = child_process.execSync(`lsof -p ${process.pid}`);

这将同步运行由当前运行的Node.js进程过滤的lsof,并通过缓冲区返回结果。

然后使用console.log(openFiles.toString())将缓冲区转换为字符串并记录结果。

吹风笛,你只需要零钱

FS.readFile(filename, onRealRead);

=>

var bagpipe = new Bagpipe(10);

bagpipe.push(FS.readFile, filename, onRealRead))

风笛帮助你限制平行动作。详情:https://github.com/JacksonTian/bagpipe