简体   繁体   English

上传前文件未在node.js中关闭

[英]File not closing in node.js before upload

I'm trying to upload a file to S3 after creation however the file doesn't seem to be closing with the fs.createWriteStream. 我正在尝试在创建后将文件上传到S3,但是该文件似乎没有通过fs.createWriteStream关闭。 Hence I keep getting a 0 byte file being uploaded. 因此,我一直在上传一个0字节的文件。

function createManifest(manfile) {
console.log(['a'].toString(), ['a', 'b'].toString());

    var arrayLength = files.length;
    var lastItem = arrayLength - 1;
    console.log( chalk.blue("The last item value is:",lastItem))
    console.log( chalk.yellow("The arrayLength value is:",arrayLength))
    var logStream = fs.createWriteStream("manny_temp.json", {'flags': 'a'});
// use {'flags': 'a'} to append and {'flags': 'w'} to erase and write a new file
//    logStream.on('open', function(fd) {
logStream.write('{'+ "\r\n");
logStream.write("\"entries\": [" + "\r\n");

    for (var i = 0; i < arrayLength; i++) {

            console.log( chalk.inverse(files[i]))
            console.log( chalk.blue("The i value is:",i))
            if ( i == lastItem) {
                logStream.write("{\"url\":\"s3://mybucket/" +files[i] + "\",\"key\":true}" + "\r\n");
            } else {
                    logStream.write("{\"url\":\"s3://mybucket/" +files[i] + "\",\"key\":true}," + "\r\n");
             }
    }
    logStream.write('    ]' + "\r\n");
    logStream.write('}');
//      }).on('end', function() {
            logStream.end();
            //fs.renameSync(logStream.path, manfile.toString());
            return callback(filepath);
//      logStream.close();
    //fs.renameSync(logStream.path, "manny.json");

  //   });
}

I've tried a multitude of ways to get the file to close so that the next function can upload the file upon creation, and even added a sleep, but it always seems to leave a hanging inode. 我尝试了多种方法来关闭文件,以便下一个函数可以在创建时上载该文件,甚至可以添加一个睡眠,但是它似乎始终会挂起一个索引节点。

Using the fs.write seems to write only one line vs writing all the lines in the array / streaming data. 与在阵列/流数据中写入所有行相比,使用fs.write似乎只写入一行。

Does anyone have a suggestion? 有人有建议吗?

You need to listen for the close event on the logStream before calling the callback. 您需要在调用回调之前logStream上的close事件。 That is what signals that the backing file descriptor has been closed (no more writing will take place). 这就是表明备份文件描述符已关闭(不会再进行写入)的信号。 I should note, this is different than listening for the finish event since finish merely indicates the stream is closed, but not necessarily that the file descriptor is closed, so it is technically less safe to rely on if you're going to do something with the file soon after). 我应该注意,这与侦听finish事件不同,因为finish仅表示流已关闭,但不一定是文件描述符已关闭,因此,如果要执行某项操作,从技术上讲,依赖它的安全性较低文件)。

Replace this: 替换为:

return callback(filepath);

with this: 有了这个:

logStream.on('close', function() {
  callback(filepath);
});

It is possible to improve on this further, by instead using the (err, result) -style callbacks common in the node ecosystem: 通过代替使用节点生态系统中常见的(err, result) -样式回调(err, result)可以进一步改善此情况:

logStream.on('close', function() {
  callback(null, filepath);
});
logStream.on('error', function(err) {
  callback(err);
});

That way you can capture any errors that may result from opening or writing to the file. 这样,您可以捕获由于打开或写入文件而导致的任何错误。

I'm also assuming you do have callback defined in a parent scope somewhere. 我还假设您确实在某个地方的父作用域中定义了callback

Your question is asked without the basic research though, Here is an attempt to make it more readable code and executable at glance. 但是,您的问题是在没有基础研究的情况下提出的,这是一种使代码一目了然的可读性和可执行性的尝试。 Hope you will find an answer with below code. 希望您能找到以下代码的答案。

If your question is still the same, re-write your question in a better way. 如果您的问题仍然相同,则以更好的方式重新编写您的问题。

var chalk = require('chalk');
var fs = require('fs');

function createManifest(manfile) {
var files = ['/test.json'];
console.log(['a'].toString(), ['a', 'b'].toString());
    var arrayLength = files.length;
    var lastItem = arrayLength - 1;
    console.log( chalk.blue("The last item value is:",lastItem))
    console.log( chalk.yellow("The arrayLength value is:",arrayLength))
    var logStream = fs.createWriteStream("manny_temp.json", {'flags': 'a'});
    logStream.write('{'+ "\r\n");
    logStream.write("\"entries\": [" + "\r\n");

    for (var i = 0; i < arrayLength; i++) {

            console.log( chalk.inverse(files[i]))
            console.log( chalk.blue("The i value is:",i))
            if ( i == lastItem) {
                logStream.write("{\"url\":\"s3://mybucket/" +files[i] + "\",\"key\":true}" + "\r\n");
            } else {
                    logStream.write("{\"url\":\"s3://mybucket/" +files[i] + "\",\"key\":true}," + "\r\n");
             }
    }
    logStream.write('    ]' + "\r\n");
    logStream.write('}'); 
    logStream.end();
    logStream.on('finish', function(){
        fs.renameSync("manny_temp.json", "manny.json"); 
    }); 
};

createManifest();

mscdex is nearly right. mscdex几乎是正确的。 You need to listen for the 'finish' event, not the 'close' event because that is emitted by readable streams but this is a writable stream. 您需要侦听“完成”事件,而不是“关闭”事件,因为该事件由可读流发出,但这是可写流。

And you can pass your handler to 'end' instead. 您可以将处理程序传递给“结束”。 See https://nodejs.org/dist/latest-v4.x/docs/api/stream.html#stream_event_finish 参见https://nodejs.org/dist/latest-v4.x/docs/api/stream.html#stream_event_finish

logStream.end(function() {
    fs.renameSync("manny_temp.json", "manny.json");
    callback(filepath);
});

I tried to edit mscdex's answer to this effect but this was rejected for some reason. 我试图编辑mscdex对此的答案,但是由于某种原因,它被拒绝了。

Edit: You'd need to define or pass in 'callback', as well as 'filepath'. 编辑:您需要定义或传递“回调”以及“文件路径”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM