node.js - 即使文件存在,readFileSync 也不返回任何数据
问题描述
tl;博士
readFileSync 在读取约 24kb 的文件后返回大小为零的结果。没有错误被抛出。
不那么tl;博士
首先,我以编程方式使用 browserify 构建三个 JS 文件。这成功完成,文件出现在我期望的位置,文件名是我期望的,手动检查文件大小和内容都符合预期。
稍后在代码执行过程中,我使用readFileSync
重新读取这些文件,并将它们与其他文件连接以创建捆绑包。问题是,对于三个生成的文件之一,一切都很好,但对于另外两个,readFileSync
总是返回零长度结果。
同样,这些文件肯定包含数据。
在文件上运行fs.statSync
确实显示大小为 0 :-/ 例如,以下是其中一个文件的统计信息:
Stats {
dev: 16777220,
mode: 33188,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4194304,
ino: 10106323,
size: 0,
blocks: 0,
atimeMs: 1536239893064.3716,
mtimeMs: 1536239915850.5076,
ctimeMs: 1536239915850.5076,
birthtimeMs: 1536239886797.752,
atime: 2018-09-06T13:18:13.064Z,
mtime: 2018-09-06T13:18:35.851Z,
ctime: 2018-09-06T13:18:35.851Z,
birthtime: 2018-09-06T13:18:06.798Z
}
对于我的生活,我无法弄清楚为什么 Node/OS 似乎认为这些文件是空的。有没有人遇到过这种情况?如果问题过于广泛,请道歉。
更新:原来用 browserify 构建的所有三个文件的行为都是一样的。一个似乎工作,因为它捆绑另一个 JS 文件。当我单独运行代码时,我也没有返回任何数据。
这是使用 browserify 生成文件的代码:
const entryFiles = config.editorBundles.split(',');
for (let file in entryFiles) {
let currentFile = entryFiles[file];
let outputBaseFileName = currentFile.substr(
0,
currentFile.indexOf('.js')
);
let writableOutputFile = fs.createWriteStream(
path.join(__dirname, `${outputBaseFileName}-bundle.js`)
);
try {
let brfy = browserify(
path.join(__dirname, entryFiles[file])
).bundle();
brfy.pipe(writableOutputFile);
} catch (error) {
console.error('MDN-BOB: (bundler.js/@compileJS)', error);
reject(
Error(
'MDN-BOB: (bundler.js/@compileJS) Error while bundling and writing'
)
);
}
我想知道 this( brfy.pipe(writableOutputFile);
) 写入文件的方式是否导致了问题?
解决方案
在考虑了更多之后,查看了代码,以及来自@dpopp07( .pipe
is async) 的超级有用的评论,我意识到这里发生的事情是一个竞争条件。在读取发生时,写入很可能还没有完成。
在这种情况下,我不得不重构工作流程是如何发生的。每件工作都已经被包裹在一个Promise
但是中,看到有一些异步工作发生,这并没有解决问题(很明显;))。
因此,我将之前的循环更改for
为以下函数:
function processAndWrite() {
const entryFiles = config.editorBundles.split(',');
let filePromises = [];
for (let file in entryFiles) {
let promise = new Promise((resolve, reject) => {
let currentFile = entryFiles[file];
let outputBaseFileName = currentFile.substr(
0,
currentFile.indexOf('.js')
);
let outputFilename = `${outputBaseFileName}-bundle.js`;
let writableOutputFile = fs.createWriteStream(
path.join(__dirname, outputFilename)
);
try {
let reader = browserify(
path.join(__dirname, entryFiles[file])
).bundle();
let writer = reader.pipe(writableOutputFile);
reader.on('end', () => {
resolve(`${outputFilename} written to disk`);
});
} catch (error) {
reject(
Error('MDN-BOB: (bundler.js/@compileJS) Error compiling JS')
);
}
});
filePromises.push(promise);
}
return filePromises;
}
然后我使用Promise.all
传入的数组filePromises
。一旦所有这些承诺完成,我就会继续执行程序的其余部分。这可确保文件在稍后读取之前肯定已完成写入。w00t
推荐阅读
- r - 函数`grDevices:::C_col2rgb`的源代码?
- javascript - 如何使用 Jest 共享多个套件中的测试用例?
- android - 三星的应用程序权限监视器不断提醒我的用户有关我的应用程序
- hyperledger-fabric - Hyperledger 结构:余额转移:执行 ./runApp.sh 时出错
- javascript - Web API 安全 javascript 客户端
- swift - 如何从超级协议中获得一致的协议?
- ava - ava 对快照属性匹配器的支持
- javascript - 基于数字属性并将字符串移动到最后
- c# - 为什么从 Cancel 抛出工作流异常时没有捕获到?
- visual-studio-2019 - 如何为多项目解决方案配置 vcpkg