private void FlushBlock(bool lastBlock) { compressor.Dispose(); int compressedBlockSize = (int)outputBuffer.Length; Debug.Assert(spaceLeftInBlock == 0 || lastBlock); CompressedWriteStream.LogLine("FlushBlock: lastBlock " + lastBlock + " compressedBlockSize = 0x" + compressedBlockSize.ToString("x") + " uncompresseSize=0x" + (blockSize - spaceLeftInBlock).ToString("x")); CompressedWriteStream.LogLine("Block header placed at filePosition=0x" + outputStream.Position.ToString("x")); // Write the block out prepended with its blockSize if (lastBlock) { WriteInt(outputStream, -compressedBlockSize); WriteInt(outputStream, blockSize - spaceLeftInBlock); // write the uncompressed blockSize too. } else { compressedBlockSizes.Add(compressedBlockSize); WriteInt(outputStream, compressedBlockSize); } outputStream.Write(outputBuffer.GetBuffer(), 0, compressedBlockSize); // TODO remove outputStream.Write(new byte[compressedBlockSize], 0, compressedBlockSize); CompressedWriteStream.LogLine("After write, filePosition=0x" + outputStream.Position.ToString("x")); }
protected override void Dispose(bool disposing) { if (!disposing) { int lastBlockByteCount = blockSize - spaceLeftInBlock; // Write out the last block FlushBlock(true); // Write out the table of block sizes (to allow for efficient arbitrary seeking). CompressedWriteStream.LogLine("Writing offset table starting at 0x" + outputStream.Position.ToString("x")); long blockOffset = positionOfFirstBlock; foreach (int compressedBlockSize in compressedBlockSizes) { WriteLong(outputStream, blockOffset); blockOffset += (compressedBlockSize + 4); // Add the total blockSize (with header) of the previous block } WriteLong(outputStream, blockOffset); CompressedWriteStream.LogLine("Writing offset table count " + (compressedBlockSizes.Count + 1) + " uncompressed Left = 0x" + lastBlockByteCount.ToString("x")); // remember the count of the table. WriteInt(outputStream, compressedBlockSizes.Count + 1); // and the number of uncompressed bytes in the last block WriteInt(outputStream, lastBlockByteCount); if (!leaveOpen) { outputStream.Dispose(); } } base.Dispose(disposing); }
public static void SizeTest(string inputFilePath) { Console.WriteLine("In size tests"); for (int blockSize = 1024; blockSize <= 256 * 1024; blockSize *= 2) { string compressedFilePath = Path.ChangeExtension(inputFilePath, "." + blockSize.ToString() + ".compressed"); using (Stream compressor = new CompressedWriteStream(File.Create(compressedFilePath), blockSize, false)) StreamUtilities.CopyFromFile(inputFilePath, compressor); double percent = 100.0 * (new FileInfo(compressedFilePath).Length) / (new FileInfo(inputFilePath).Length); Console.WriteLine("Blocksize " + blockSize.ToString().PadLeft(7) + " compression " + percent.ToString("f2") + "%. Placed in file " + compressedFilePath); } }
public static void Tests() { string testOrig = "text.orig"; string testCompressed = "text.compressed"; for (int fileSize = 1023; fileSize <= 1025; fileSize++) { CreateDataFile(testOrig, fileSize); FileStream origData = File.OpenRead(testOrig); // Try writing in various block sizes // TODO more sizes? for (int i = 1; i < 256; i += 37) { CompressedWriteStream compressor = new CompressedWriteStream(File.Create(testCompressed), 64, false); origData.Position = 0; CopyInChunks(origData, compressor, i); compressor.Close(); CompressedReadStream decompressor = new CompressedReadStream(testCompressed); origData.Position = 0; Debug.Assert(CompareStreams(origData, decompressor, 1024 * 16)); decompressor.Close(); } CompressedReadStream lengthTest = new CompressedReadStream(testCompressed); Debug.Assert(lengthTest.Length == origData.Length); lengthTest.Close(); // Try reading back in various seek positions. for (int blockSize = 20; blockSize < 300; blockSize += 47) { CompressedReadStream decompressor = new CompressedReadStream(testCompressed); for (int seekPosition = 0; seekPosition <= 1024; seekPosition += 16 * 3) { CompareStreams(origData, decompressor, blockSize, seekPosition); } decompressor.Close(); } origData.Close(); } }
/// <summary> /// Initializes the current block to point at the begining of the block (a block is the length as /// well as the data) that starts at the uncompressed location 'uncompressedBlockStart' which as the /// cooresponding compressed location 'compressedBlockStart'. /// </summary> private void FillBlock(long uncompressedBlockStart, long compressedBlockStart) { CompressedWriteStream.LogLine("FillBlock: uncompressedBlockStart 0x" + uncompressedBlockStart.ToString("x") + " compressedBlockStart 0x" + compressedBlockStart.ToString("x")); // Advance the uncompressed position uncompressedBlockStartPosition = uncompressedBlockStart; // and set the compressed stream to just past this block's data compressedData.Position = compressedBlockStart; // Read in the next block' blockSize (both compressed and uncompressed) uncompressedBlockSize = maxUncompressedBlockSize; int compressedBlockSize = ReadInt(compressedData); lastBlock = false; if (compressedBlockSize < 0) { compressedBlockSize = -compressedBlockSize; uncompressedBlockSize = ReadInt(compressedData); lastBlock = true; } Debug.Assert(compressedBlockSize <= maxUncompressedBlockSize * 3); // I have never seen expansion more than 2X Debug.Assert(uncompressedBlockSize <= maxUncompressedBlockSize); if (decompressor != null) { decompressor.Dispose(); } // Get next clump of data. decompressor = new DeflateStream(compressedData, CompressionMode.Decompress, true); // Set the uncompressed and compressed data pointers. uncompressedDataLeft = uncompressedBlockSize; nextCompressedBlockStartPosition = compressedData.Position + compressedBlockSize; CompressedWriteStream.LogLine("FillBlock compressedBlockSize = 0x" + compressedBlockSize.ToString("x") + " lastblock = " + lastBlock); CompressedWriteStream.LogLine("FillBlock: DONE: uncompressedDataLeft 0x" + uncompressedDataLeft.ToString("x") + " nextCompressedBlockStartPosition 0x" + nextCompressedBlockStartPosition.ToString("x")); }
public static void CompressFile(string inputFilePath, string compressedFilePath) { using (Stream compressor = new CompressedWriteStream(compressedFilePath)) Utilities.StreamUtilities.CopyFromFile(inputFilePath, compressor); }
public static void DecompressFile(string compressedFilePath, string outputFilePath) { using (Stream decompressor = new CompressedWriteStream(compressedFilePath)) Utilities.StreamUtilities.CopyToFile(decompressor, outputFilePath); }