几天来,我一直在寻找一个有效的错误解决方案
错误: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
在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
我今天遇到了这个问题,没有找到好的解决方案,我创建了一个模块来解决它。我受到@fbartho的代码片段的启发,但希望避免覆盖fs模块。
我写的模块是Filequeue,你使用它就像fs:
var Filequeue = require('filequeue');
var fq = new Filequeue(200); // max number of files to open at once
fq.readdir('/Users/xaver/Downloads/xaver/xxx/xxx/', function(err, files) {
if(err) {
throw err;
}
files.forEach(function(file) {
fq.readFile('/Users/xaver/Downloads/xaver/xxx/xxx/' + file, function(err, data) {
// do something here
}
});
});