nodejs中文件的原子write/read
atomic write/read of a file in nodejs
我的 nodejs 应用程序是围绕 "project file" 构建的。
此应用程序的几个模块(按 "module",我的意思是我项目的一个简单 javascript 文件)需要通过流 (fs.createReadStream, fs.createWriteStream), 由于这些模块是相互独立执行的, 有时起源于 websocket 事件 (例如), 我需要对项目文件进行 save/load 操作 原子。
表示以下场景:
- moduleA写入工程文件
- 同时,在模块A写完文件之前,模块B要读它=>理想情况下,它应该等待模块A的写操作(目前,它读取一个部分写入的文件并检测到一个错误)在真正读取文件之前
nodejs 是否能够在本机执行此操作,还是我必须在我的 read/write 流系统上构建一种原子包装器?
据我所知,没有内置任何东西。不过,有一些模块(例如 redis-lock)实现了锁定机制。
如果您 运行 在单个非集群服务器上,您可能可以应付实现一个简单的本地锁。
这可能会给你一个想法:
var Fs = require("fs"),
LOCK = require ("os").tmpdir () + '/foo-lock.';
function transLock(id, cb) {
Fs.open(LOCK + id, "wx", function(err, fd) {
if (err) {
// someone else has created the file
// or something went wrong
cb(err);
} else {
Fs.close(fd, function(err) {
// there should be no error here except weird stuff
// like EINTR which must be ignored on Linux
cb();
});
}
});
}
function transUnlock(id) {
Fs.unlink(LOCK + id, function(err) {
if (err) {
// something is wrong and nothing we can do except
// perhaps log something or do some background cleanup
}
});
}
function main() {
var id = "some-unique-name";
transLock(id, function(err) {
if (err)
console.log(err);
else {
// ... do your stuffs ...
transUnlock(id);
}
});
}
main();
我的 nodejs 应用程序是围绕 "project file" 构建的。
此应用程序的几个模块(按 "module",我的意思是我项目的一个简单 javascript 文件)需要通过流 (fs.createReadStream, fs.createWriteStream), 由于这些模块是相互独立执行的, 有时起源于 websocket 事件 (例如), 我需要对项目文件进行 save/load 操作 原子。
表示以下场景:
- moduleA写入工程文件
- 同时,在模块A写完文件之前,模块B要读它=>理想情况下,它应该等待模块A的写操作(目前,它读取一个部分写入的文件并检测到一个错误)在真正读取文件之前
nodejs 是否能够在本机执行此操作,还是我必须在我的 read/write 流系统上构建一种原子包装器?
据我所知,没有内置任何东西。不过,有一些模块(例如 redis-lock)实现了锁定机制。 如果您 运行 在单个非集群服务器上,您可能可以应付实现一个简单的本地锁。
这可能会给你一个想法:
var Fs = require("fs"),
LOCK = require ("os").tmpdir () + '/foo-lock.';
function transLock(id, cb) {
Fs.open(LOCK + id, "wx", function(err, fd) {
if (err) {
// someone else has created the file
// or something went wrong
cb(err);
} else {
Fs.close(fd, function(err) {
// there should be no error here except weird stuff
// like EINTR which must be ignored on Linux
cb();
});
}
});
}
function transUnlock(id) {
Fs.unlink(LOCK + id, function(err) {
if (err) {
// something is wrong and nothing we can do except
// perhaps log something or do some background cleanup
}
});
}
function main() {
var id = "some-unique-name";
transLock(id, function(err) {
if (err)
console.log(err);
else {
// ... do your stuffs ...
transUnlock(id);
}
});
}
main();