TarOutputStream doesn't flush buffer on Finish()
When you call Finish() on the TarOutputStream, it doesn't flush everything.
Finish():
public void Finish()
{
if ( IsEntryOpen )
{
CloseEntry();
}
WriteEofBlock();
}
However, Close() includes a buffer.Close() call:
public override void Close()
{
if ( !isClosed )
{
isClosed = true;
Finish();
buffer.Close();
}
}
This effectively flushes the TarBuffer. The upshot is that, if you want to have all of the data flushed, you need to close the TarOutputStream, which will automatically close the Stream object that you gave it. The exception for this is with the GZIP functionality, whose GzipOutputStream has a IsStreamOwner property that provides you the option of -not- closing the base stream.
This means that in order to get all of the data out of the Stream, you need to either use a MemoryStream wrapped by GzipOutputStream, or use a FileStream so that you can recover the data after the mandatory close.
For this scenario you should be setting IsStreamOwner = false on the TarOutputStream:
var ms = new MemoryStream();
var tos = new TarOutputStream(ms);
tos.IsStreamOwner = false;
// Write a bunch of entries...
tos.CloseEntry()
tos.Close();
I'm going to label this a bug, but I think it's more of a documentation bug.
-Neil
My suggestion would be to add the flush to Finish() as well but also mark it as deprecated, suggesting the combination of IsStreamOwner and Dispose() (preferably using a using scope)