You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am trying to close a writable stream using end() with a callback. However, when end() calls endWritable() and state.finished is set to false so the callback is set to trigger when the finish event triggers. The problem is the state.finished flag is only set within finishMaybe(). This routine is only called from endWritable() and afterWrite(). However, once end() is called you cannot write more data to the stream to trigger afterWrite() to make state.finished = true. It would seem that the end() callback only works when the state.finished is true.
I compared the 5.1.1 version of the code with the current master head within git. There have really been no changes to this area of the code.
My question is, How do I get the end() callback to work? Is there a problem in the code? If so, is there a workaround? (so far I don't see one) Thanks for the time and any help.
The code is rather large. To get a working example would be a bit of work, but basically the code is:
wavFile = fs.createReadStream( filename );
usbAudioWriter = getWritableStreamSomehow(); // calls a module that inherits from the Writable to stream over our USB API (The end code calls the Writeable.end as is.
wavFile.pipe( usbAudioWriter );
...
// When closing the stream down
usbAudioWriter.end( function() {
// Do the close here...
console.log("End Called");
} );
Like I mentioned before, when end() is called state.finished is false.
If I attempt to force the afterWrite() with something like the following code: usbAudioWriter.write( Buffer("\0") );
I get the error: write after end
If this is not enough to go on, please let me know. I can attempt to reduce the problem to a testable use case. I am just working off of code inspection, but it seems if state.finished is false when endWritable() is called, the callback passed into end() will never be called--I could however be wrong. I am still rather new to all the streaming code.
Ah! The docs for .pipe() might help clarify things. Normally, when piping from a stream to another, when the reading side ends, the writing sides ends, too, so you can’t call .end() again. If you want to know when writing to a stream ended, use the 'finish' event, i.e.
// When closing the stream downusbAudioWriter.on('finish',function(){// Do the close here...console.log("End Called");});
If there’s something you need to do before the writer stream ends, you should be able to override the default behaviour using {end: false} and ending the writable stream yourself:
wavFile=fs.createReadStream(filename);usbAudioWriter=getWritableStreamSomehow();// calls a module that inherits from the Writable to stream over our USB API (The end code calls the Writeable.end as is.wavFile.pipe(usbAudioWriter,{end: false});
...
// When closing the stream downwavFile.on('finish',function(){// do things...usbAudioWriter.end(function(){// Do the close here...console.log("End Called");});});
Reacted by MatiasComercio, Jannik Weyrich, Matan Lieberman and Pradeep
I am working on a similar thing where I need to download a zip into to an already open file(that has a valid file descriptor) and also use this file descriptor later on to unzip the file. If I dont use pipe: false then the filestream end is coming and accessing the file descriptor for the unzip is giving an error because it is already closed. Is there a way to just know when the data has been flushed to the underlying stream without closing it ?
Activity
addaleax commentedon May 18, 2016
Could you provide e.g. a minimal snippet of code with an example where calling
.end(…)does not work?tysenmoore-xse commentedon May 18, 2016
The code is rather large. To get a working example would be a bit of work, but basically the code is:
Like I mentioned before, when
end()is calledstate.finishedis false.If I attempt to force the
afterWrite()with something like the following code:usbAudioWriter.write( Buffer("\0") );I get the error:
write after endIf this is not enough to go on, please let me know. I can attempt to reduce the problem to a testable use case. I am just working off of code inspection, but it seems if
state.finishedis false whenendWritable()is called, the callback passed intoend()will never be called--I could however be wrong. I am still rather new to all the streaming code.addaleax commentedon May 18, 2016
Ah! The docs for
.pipe()might help clarify things. Normally, when piping from a stream to another, when the reading side ends, the writing sides ends, too, so you can’t call.end()again. If you want to know when writing to a stream ended, use the'finish'event, i.e.If there’s something you need to do before the writer stream ends, you should be able to override the default behaviour using
{end: false}and ending the writable stream yourself:tysenmoore-xse commentedon May 19, 2016
In my use case the wav file being played is on a continuous loop, so its
end()is never called.However, based on your suggestions I was able to get it working similar to your solution. Thanks so much for the time and help.
akshita31 commentedon May 1, 2018
I am working on a similar thing where I need to download a zip into to an already open file(that has a valid file descriptor) and also use this file descriptor later on to unzip the file. If I dont use pipe: false then the filestream
endis coming and accessing the file descriptor for the unzip is giving an error because it is already closed. Is there a way to just know when the data has been flushed to the underlying stream without closing it ?