Nodejs 使用fs.readFile高频读取和fs.writeFile高频写入时,出现问题
Nodejs 使用fs.readFile高频读取和fs.writeFile高频写入时,出现问题
我是建一个索引文件,用来做好友的模糊查询。但是在批量写入索引文件的时候,就会出现各种问题。 例如
undefined:945
})
^
SyntaxError: Unexpected token }
at Object.Function (<anonymous>)
at /Volumes/macFile/nodeProject/cngouwo/routes/api/addFriend.js:21:23
at fs.js:266:14
at Object.oncomplete (fs.js:107:15)
Process finished with exit code 8
不仅仅这一个错误。各种各样的错误。
不知道为何如此?
代码奉上:
var fs = require('fs'),
util = require('util');
module.exports = function(req,res){
var id = req.body.id,
name = req.body.name,
friend = {};
fs.readFile('out.txt',function(err,data){
if(err){
var _collection = friend.collection = {},
_index = friend.index = {};
}
else{
var friends = data.toString();
friend = (new Function("return "+friends))();
var _collection = friend.collection,
_index = friend.index;
}
_collection['id_'+id] = name;
for(var x = 0 ; x < name.length ; x++){
if(!_index[name[x]])
_index[name[x]] = {};
if(!_index[name[x]]['id_'+id]){
_index[name[x]]['id_'+id] = {};
_index[name[x]]['id_'+id]['s'] = 1;
_index[name[x]]['id_'+id]['i'] = [x];
}else{
_index[name[x]]['id_'+id]['s'] += 1;
_index[name[x]]['id_'+id]['i'].push(x);
}
};
var json = util.inspect(friend,false,4);
fs.writeFile("out.txt", json, function(err) {
friend = null;
json = null;
if(err){
res.send('失败')
}else{
res.send({ms:'cd'})
}
});
});
}
9 回复
当使用 fs.readFile
和 fs.writeFile
高频读取和写入文件时,可能会遇到多种问题,比如数据竞争、内存泄漏、性能瓶颈等。以下是一些可能的原因及解决方案:
问题分析
- 数据竞争:由于
fs.readFile
是异步操作,在频繁调用时,可能会导致文件状态不一致或数据混乱。 - 内存泄漏:频繁地创建临时变量和对象,可能会导致内存泄漏。
- 性能瓶颈:频繁的 I/O 操作会阻塞事件循环,导致 Node.js 应用性能下降。
示例代码优化
为了减少这些问题,可以考虑以下优化措施:
- 合并写入操作:将多次写入合并为一次写入,减少 I/O 操作。
- 使用流:使用
fs.createWriteStream
和fs.createReadStream
来处理大量数据。 - 避免重复读取:缓存已读取的数据,而不是每次都从文件中读取。
示例代码
var fs = require('fs');
var util = require('util');
let cachedData = {};
module.exports = function(req, res) {
const id = req.body.id;
const name = req.body.name;
// 读取缓存中的数据,如果没有则从文件中读取
if (!cachedData.data) {
fs.readFile('out.txt', 'utf-8', (err, data) => {
if (err) {
cachedData.data = {};
} else {
cachedData.data = JSON.parse(data);
}
updateCache(id, name);
writeToFile();
});
} else {
updateCache(id, name);
writeToFile();
}
};
function updateCache(id, name) {
const friend = cachedData.data;
friend.collection = friend.collection || {};
friend.index = friend.index || {};
friend.collection['id_' + id] = name;
for (let i = 0; i < name.length; i++) {
const char = name[i];
if (!friend.index[char]) {
friend.index[char] = {};
}
if (!friend.index[char]['id_' + id]) {
friend.index[char]['id_' + id] = { s: 1, i: [i] };
} else {
friend.index[char]['id_' + id].s += 1;
friend.index[char]['id_' + id].i.push(i);
}
}
}
function writeToFile() {
const jsonData = JSON.stringify(cachedData.data, null, 2);
fs.writeFile('out.txt', jsonData, (err) => {
if (err) {
res.send('失败');
} else {
res.send({ ms: 'cd' });
}
});
}
解释
- 缓存数据:使用
cachedData
对象来缓存已读取的数据,减少文件读取次数。 - 更新缓存:每次请求时,更新缓存中的数据。
- 合并写入:将所有更新操作完成后,一次性写入文件,减少 I/O 操作。
通过这些优化,可以显著减少高频读写带来的问题,并提高应用的整体性能。
求大神帮助
顺便说一下,报错服务终止后,重新启动服务,从报错的数据继续写,就又可以跑。。
friend = (new Function("return "+friends))();
这句出现的问题吧?
这个应该是数据还没写完你又继续读, writeFile的时候应该没有锁住文件读的, 你可能才写了一半就开始读了!
在回调里面写的writeFile,应该是在readFile结束后才开始write的吧。
friend = (new Function("return "+friends))();
这句好费解。什么意思啊 为什么这样用
没有什么费解的啊 new Function方法可以定义一个function(function body接受字符串), 具体请看文档…
在使用 Node.js 的 fs.readFile
和 fs.writeFile
进行高频读写操作时,可能会遇到一些常见的问题,比如文件竞争、内存泄漏、性能瓶颈等。以下是一些可能的原因及改进建议:
原因分析
- 文件竞争:频繁的读写操作可能导致文件系统竞争,尤其是在多进程或分布式环境中。
- 同步问题:使用
fs.readFile
和fs.writeFile
时,如果操作没有正确处理异步回调,可能会导致数据丢失或不一致。 - 内存泄漏:频繁地创建和销毁对象,如果不进行适当的清理,可能导致内存泄漏。
示例改进代码
var fs = require('fs');
var util = require('util');
module.exports = function(req, res) {
var id = req.body.id;
var name = req.body.name;
fs.readFile('out.txt', 'utf8', function(err, data) {
if (err && err.code !== 'ENOENT') { // 文件不存在时忽略错误
return res.status(500).send('读取文件时出错');
}
let friend = data ? JSON.parse(data) : { collection: {}, index: {} };
friend.collection['id_' + id] = name;
for (let i = 0; i < name.length; i++) {
if (!friend.index[name[i]]) {
friend.index[name[i]] = {};
}
if (!friend.index[name[i]]['id_' + id]) {
friend.index[name[i]]['id_' + id] = {
s: 1,
i: [i]
};
} else {
friend.index[name[i]]['id_' + id].s += 1;
friend.index[name[i]]['id_' + id].i.push(i);
}
}
fs.writeFile('out.txt', JSON.stringify(friend), 'utf8', function(err) {
if (err) {
return res.status(500).send('写入文件时出错');
}
res.send({ ms: 'cd' });
});
});
};
解释
- 文件读取:使用
fs.readFile
读取文件,并指定编码为utf8
,避免后续转换。 - 错误处理:检查
err
并确保只在实际错误发生时处理它,而不是忽略所有错误。 - JSON 操作:将读取的数据解析为 JSON 对象,而不是使用
new Function
,这可以避免潜在的安全问题。 - 写入文件:使用
fs.writeFile
将更新后的 JSON 数据写回文件,同样指定编码为utf8
。
通过这些改进,可以提高代码的健壮性和可维护性,减少高频读写操作带来的问题。