【发布时间】:2016-07-18 18:01:40
【问题描述】:
以下代码在 OSX 上的 dev 中运行时从未失败,但在位于 Docker 容器中的生产环境中每次都失败:
DataSyncController.js
let jsonFile = await FileSystemService.ParseCsvToJson(fileName);
if (!jsonFile.success)
return res.json({ success: false });
let parsedJson = await FileSystemService.ParseJsonFile({ file: jsonFile.fileName });
if (!parsedJson.success)
return res.json({ success: false });
FileSystemService.js
static async ParseJsonFile(params)
{
return new Promise((resolve, reject) =>
{
try
{
fs.readFile(jsonFilePath, 'utf-8', (err, data) =>
{
if (err)
{
console.log('fs.readFile() error: ', err);
resolve({ success: false });
}
var file = [];
try
{
// This fails every time in the Docker container
// Error is [Unexpected end of input]
// At this point I've seend `data` evaluate to '',
// <buffer >, undefined and partial JSON data
file = JSON.parse(data);
}
catch(e)
{
console.log('ERROR parsing JSON file: ', e);
return resolve({ success: false });
}
// Do Stuff
return resolve({ success: true });
});
}
catch(exception)
{
console.error(exception);
resolve({ success: false });
}
});
}
似乎在 Docker 容器中,JSON 文件在读取时尚未完成写入(例如,如果我将整个 fs.readFile() 块放入 timeout 并阻止它运行,则 JSON.parse() 有效5 秒),但我不明白这是怎么可能的,也不知道为什么在 Docker 容器中而不是在我的本地机器上会出现这种情况。一如既往,我们非常感谢您的任何想法。
更新
根据要求,这里是 ParseCsvToJson 方法的实现,它实际上将 JSON 文件写入磁盘。请注意,在 Docker 容器的开发和生产中,写入的 JSON 文件虽然很大(大约 4,400 条记录),但看起来还不错。
var Converter = require("csvtojson").Converter;
var filePath = `${config.root}/server/uploadDir`;
static async ParseCsvToJson(fileName)
{
return new Promise((resolve, reject) =>
{
try
{
let fileNameWithoutExtension = fileName.replace('.csv', '');
const jsonFilePath = `${filePath}/${fileNameWithoutExtension}.json`;
const csvFilePath = `${filePath}/${fileName}`;
// The parameter false will turn off final result construction.
// It can avoid huge memory consumption while parsing.
// The trade off is final result will not be populated to end_parsed event.
var csvConverter = new Converter({ constructResult: false, toArrayString: true });
var readStream = fs.createReadStream(csvFilePath);
var writeStream = fs.createWriteStream(jsonFilePath);
readStream.pipe(csvConverter).pipe(writeStream);
resolve({ success: true, fileName: `${fileNameWithoutExtension}.json` });
}
catch(exception)
{
console.error(exception);
resolve({ success: false });
}
});
}
【问题讨论】:
-
我很确定你的
ParseJsonFile()函数应该拒绝,而不是用“success = false”解决。 -
是的,这实际上在我的更改清单上。我这样做是有原因的,但老实说,我现在不记得那是什么。
-
也显示
ParseCsvToJson的实现。 (我认为这个虽然名字很古怪,但实际上是在写入 JSON 文件,所以我怀疑那里的错误) -
@Tomalak:我添加了请求的代码。
-
而那是你应该问的问题,这里的这个问题是一个红鲱鱼。制作一个抽象的、最小化的两个异步函数样本来重现这种情况(在一个新问题中)。
标签: node.js docker async-await fs