GZipStream and decompression - c#

I have code that should do the compression:
FileStream fs = new FileStream("g:\\gj.txt", FileMode.Open);
FileStream fd = new FileStream("g:\\gj.zip", FileMode.Create);
GZipStream csStream = new GZipStream(fd, CompressionMode.Compress);
byte[] compressedBuffer = new byte[500];
int offset = 0;
int nRead;
nRead = fs.Read(compressedBuffer, offset, compressedBuffer.Length);
while (nRead > 0)
{
csStream.Write(compressedBuffer, offset, nRead);
offset = offset + nRead;
nRead = fs.Read(compressedBuffer, offset, compressedBuffer.Length);
}
fd.Close();
fs.Close();
and I think it does, but I want to decompress what was compressed the way above. I do somethink like that:
FileStream fd = new FileStream("g:\\gj.new", FileMode.Create);
FileStream fs = new FileStream("g:\\gj.zip", FileMode.Open);
GZipStream csStream = new GZipStream(fs, CompressionMode.Decompress);
byte[] decompressedBuffer = new byte[500];
int offset = 0;
int nRead;
nRead=csStream.Read(decompressedBuffer, offset, decompressedBuffer.Length);
while (nRead > 0)
{
fd.Write(decompressedBuffer, offset, nRead);
offset = offset + nRead;
nRead = csStream.Read(decompressedBuffer, offset, decompressedBuffer.Length);
}
fd.Close();
fs.Close();
and here it doesn't... I've got nRead = 0 befeore entering the loop... What I do wrong??
The test file I use is the simpliest TEXT file (size: 104 bytes)...

My first thought is that you haven't closed csStream. If you use using this happens automatically. Since gzip buffers data, you could be missing some.
Secondly; don't increment offset; that is the offset in the buffer (not the stream). Leave at 0:
using (Stream fs = File.OpenRead("gj.txt"))
using (Stream fd = File.Create("gj.zip"))
using (Stream csStream = new GZipStream(fd, CompressionMode.Compress))
{
byte[] buffer = new byte[1024];
int nRead;
while ((nRead = fs.Read(buffer, 0, buffer.Length))> 0)
{
csStream.Write(buffer, 0, nRead);
}
}
using (Stream fd = File.Create("gj.new.txt"))
using (Stream fs = File.OpenRead("gj.zip"))
using (Stream csStream = new GZipStream(fs, CompressionMode.Decompress))
{
byte[] buffer = new byte[1024];
int nRead;
while ((nRead = csStream.Read(buffer, 0, buffer.Length)) > 0)
{
fd.Write(buffer, 0, nRead);
}
}

The two methods I have are like James Roland mentioned.
private static byte[] Compress(HttpPostedFileBase file)
{
using var to = new MemoryStream();
using var gZipStream = new GZipStream(to, CompressionMode.Compress);
file.InputStream.CopyTo(gZipStream);
gZipStream.Flush();
return to.ToArray();
}
private static byte[] Decompress(byte[] compressed)
{
using var from = new MemoryStream(compressed);
using var to = new MemoryStream();
using var gZipStream = new GZipStream(from, CompressionMode.Decompress);
gZipStream.CopyTo(to);
return to.ToArray();
}
However, I'm using an upload with
Request.Files[0]
then compress and save in the db. Then I pull the img out, decompress and set a src with
$"data:image/gif;base64,{ToBase64String(Decompress(img))}";

Related

GZipStream sum compressing blocks to file

I make an archiver with block-by-block reading and file compression. I put the compressed block in FileStream.
I am reading the 5 mb block. The problem is that if I compress a pic of 8 mb, then when I pull it out of the resulting archive, its sum-hash does not match the original and it opens pic halfway, and the size is the same... I don’t know what to try. I ask for help.
Read chunk void:
private byte[] ReadChunk(int chunkId)
{
using (var inFile = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
long filePosition = chunkId * chunkDataSize;
int bytesRead;
if (inFile.Length - filePosition <= chunkDataSize)
{
bytesRead = (int)(inFile.Length - filePosition);
}
else
{
bytesRead = chunkDataSize;
}
var lastBuffer = new byte[bytesRead];
inFile.Read(lastBuffer, 0, bytesRead);
return lastBuffer;
}
}
Compress and write void:
private void CompressBlock(byte[] bytesTo)
{
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream gs = new GZipStream(ms, CompressionMode.Compress))
{
gs.Write(bytesTo, 0, bytesTo.Length);
}
byte[] compressedData = ms.ToArray();
using (var outFile = new FileStream(resultFile, FileMode.Append))
{
BitConverter.GetBytes(compressedData.Length).CopyTo(compressedData, 4);
outFile.Write(compressedData, 0, compressedData.Length);
}
}
}

Why is't the file processed blocks with GZipStream and CryptoStream on C#?

I have two methods, one works, the other not.
Working method:
public static void CompressAndEncrypt(string sourceFile, string encrFile)
{
int bufferSize = 5242880;
using (var readStream = new FileStream(sourceFile, FileMode.Open, FileAccess.ReadWrite))
{
using (var writeStream = new FileStream(encrFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider();
cryptic.Key = ASCIIEncoding.ASCII.GetBytes("ABCDEFGH");
cryptic.IV = ASCIIEncoding.ASCII.GetBytes("ABCDEFGH");
using (var crypto = new CryptoStream(writeStream, cryptic.CreateEncryptor(), CryptoStreamMode.Write))
{
using (var zip = new GZipStream(crypto, CompressionMode.Compress))
{
int bytesRead = -1;
byte[] bytes = new byte[bufferSize];
while ((bytesRead = readStream.Read(bytes, 0, bufferSize)) > 0)
{
zip.Write(bytes, 0, bytesRead);
}
}
}
}
}
}
Nonworking method:
public static void CompressAndEncryptBlock(string sourceFile, string outputFile)
{
int bufferSize = 5242880;
int bytesRead;
var bytes = new byte[bufferSize];
using (var readStream = new FileStream(sourceFile, FileMode.Open, FileAccess.ReadWrite))
{
using (var writer = new FileStream(outputFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
while ((bytesRead = readStream.Read(bytes, 0, bufferSize)) > 0)
{
using (var writeStream = new MemoryStream())
{
DESCryptoServiceProvider cryptic = new DESCryptoServiceProvider();
cryptic.Key = Encoding.ASCII.GetBytes("ABCDEFGH");
cryptic.IV = Encoding.ASCII.GetBytes("ABCDEFGH");
using (var crypto = new CryptoStream(writeStream, cryptic.CreateEncryptor(), CryptoStreamMode.Write))
{
using (var zip = new GZipStream(crypto, CompressionMode.Compress, true))
{
zip.Write(bytes, 0, bytesRead);
//After that, the Capacity of writeStream (MemoryStream) is somehow greater than its Length
}
var bytes1 = new byte[writeStream.Length];
writeStream.Read(bytes1, 0, bytes1.Length);
writer.Write(bytes1, 0, bytes1.Length);
}
}
}
}
}
}
Why does the second processing of the file go wrong?
The second way I will need in the future is to transfer the file in blocks (now while I'm just testing it for writing to disk).
After using the second method, the file size is slightly smaller than when using the first method. And further, if I decrypt and decompress I get this exception:
System.IO.InvalidDataException occurred
HResult=0x80131501
Message=Invalid magic number in the GZip header. The transfer must go to the GZip stream.
Source=System
StackTrace:
at System.IO.Compression.GZipDecoder.ReadHeader(InputBuffer input)
at System.IO.Compression.Inflater.Decode()
at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
at System.IO.Compression.GZipStream.Read(Byte[] array, Int32 offset, Int32 count)
If I use the first method I can decrypt and decompress (I use only one method for decrypt and decompress).

out of memory exception in compress large files using io.compression

i am trying to not exceeded memory max size so i have to check every time if It greater than Max Memory Size Then i flush it into zip file Stream . The Problem Here it replace memory stream with existence one in file stream ,Or Is there Any way To Do the Same Rquired with Another Way ( But With Out Using Any DLL Lib)
MemoryStream memoryStream = new MemoryStream();
FileStream fileStream = new FileStream(sbZipFolderName.ToString(),FileMode.Create);
foreach (FileInfo flInfo in ListfileFolderPaths)
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Update, true))
archive.CreateEntryFromFile(flInfo.FullName, slastFolderName + "/" + flInfo.DirectoryName.Replace(new DirectoryInfo(sFolderPath.ToString()).FullName, "") + "/" + flInfo.Name);
if (memoryStream.Length > MaxSize)
{
using (fileStream = new FileStream(sFolderPath + "/" + slastFolderName + ".zip", FileMode.Create))
{
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(fileStream);
memoryStream = new MemoryStream();
}
}
}
if ((memoryStream != null) && (memoryStream.Length > 0))
memoryStream.CopyTo(fileStream);
You can use theGzip archive to compress a file.
This is the compression:
public static byte[] Compress(byte[] raw)
{
using (MemoryStream memory = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(memory,
CompressionMode.Compress, true))
{
gzip.Write(raw, 0, raw.Length);
}
return memory.ToArray();
}
}
}
And this to decompression :
static byte[] Decompress(byte[] gzip)
{
// Create a GZIP stream with decompression mode.
// ... Then create a buffer and write into while reading from the GZIP stream.
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (MemoryStream memory = new MemoryStream())
{
int count = 0;
do
{
count = stream.Read(buffer, 0, size);
if (count > 0)
{
memory.Write(buffer, 0, count);
}
}
while (count > 0);
return memory.ToArray();
}
}
}
}
Tell me if it worked.
Goodluck.

decompress a .gz file using GZipStream

I have several .gz files, and I want to decompress them one by one.
I have writen a simple code using GzipStream in C#, but got failed. I wonder a correct and useful method to achieve what I want. Thanks a lot.
private string Extrgz(string infile)
{
string dir = Path.GetDirectoryName(infile);
string decompressionFileName = dir + Path.GetFileNameWithoutExtension(infile) + "_decompression.bin";
using (GZipStream instream = new GZipStream(File.OpenRead(infile), CompressionMode.Compress))// ArgumentException...
{
using (FileStream outputStream = new FileStream(decompressionFileName, FileMode.Append, FileAccess.Write))
{
int bufferSize = 8192, bytesRead = 0;
byte[] buffer = new byte[bufferSize];
while ((bytesRead = instream.Read(buffer, 0, bufferSize)) > 0)
{
outputStream.Write(buffer, 0, bytesRead);
}
}
}
return decompressionFileName;
}
You need to decompress but you set CompressionMode.Compress, replace it with CompressionMode.Decompress.
Example here.
Here:
public static void DeCompressFile(string CompressedFile, string DeCompressedFile)
{
byte[] buffer = new byte[1024 * 1024];
using (System.IO.FileStream fstrmCompressedFile = System.IO.File.OpenRead(CompressedFile)) // fi.OpenRead())
{
using (System.IO.FileStream fstrmDecompressedFile = System.IO.File.Create(DeCompressedFile))
{
using (System.IO.Compression.GZipStream strmUncompress = new System.IO.Compression.GZipStream(fstrmCompressedFile,
System.IO.Compression.CompressionMode.Decompress))
{
int numRead = strmUncompress.Read(buffer, 0, buffer.Length);
while (numRead != 0)
{
fstrmDecompressedFile.Write(buffer, 0, numRead);
fstrmDecompressedFile.Flush();
numRead = strmUncompress.Read(buffer, 0, buffer.Length);
} // Whend
//int numRead = 0;
//while ((numRead = strmUncompress.Read(buffer, 0, buffer.Length)) != 0)
//{
// fstrmDecompressedFile.Write(buffer, 0, numRead);
// fstrmDecompressedFile.Flush();
//} // Whend
strmUncompress.Close();
} // End Using System.IO.Compression.GZipStream strmUncompress
fstrmDecompressedFile.Flush();
fstrmDecompressedFile.Close();
} // End Using System.IO.FileStream fstrmCompressedFile
fstrmCompressedFile.Close();
} // End Using System.IO.FileStream fstrmCompressedFile
} // End Sub DeCompressFile
// http://www.dotnetperls.com/decompress
public static byte[] Decompress(byte[] gzip)
{
byte[] baRetVal = null;
using (System.IO.MemoryStream ByteStream = new System.IO.MemoryStream(gzip))
{
// Create a GZIP stream with decompression mode.
// ... Then create a buffer and write into while reading from the GZIP stream.
using (System.IO.Compression.GZipStream stream = new System.IO.Compression.GZipStream(ByteStream
, System.IO.Compression.CompressionMode.Decompress))
{
const int size = 4096;
byte[] buffer = new byte[size];
using (System.IO.MemoryStream memory = new System.IO.MemoryStream())
{
int count = 0;
count = stream.Read(buffer, 0, size);
while (count > 0)
{
memory.Write(buffer, 0, count);
memory.Flush();
count = stream.Read(buffer, 0, size);
}
baRetVal = memory.ToArray();
memory.Close();
}
stream.Close();
} // End Using System.IO.Compression.GZipStream stream
ByteStream.Close();
} // End Using System.IO.MemoryStream ByteStream
return baRetVal;
} // End Sub Decompress

gzipstream.copyto alternate and easy way in .net 3.5

hi
in this code in .net 4 i used copyto method of gzipstream
System.IO.MemoryStream ms = new System.IO.MemoryStream(byteArray);
GZipStream DecompressOut = new GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);
MemoryStream outmem = new MemoryStream();
DecompressOut.copyto(outmem);
FileStream outFile = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter m_streamWriter = new StreamWriter(outFile);
how can i diretly write GZipStream into MemoryStream or FileStream?
Copying between streams is pretty basic:
public static long CopyTo(this Stream source, Stream destination) {
byte[] buffer = new byte[2048];
int bytesRead;
long totalBytes = 0;
while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
destination.Write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
return totalBytes;
}
So just plug that in, and you should be sorted:
using(var ms = new MemoryStream(byteArray))
using(var gzip = new GZipStream(ms, CompressionMode.Decompress))
using (var file = new FileStream(fileName, FileMode.OpenOrCreate,
FileAccess.Write)) {
gzip.CopyTo(file);
}

Categories

Resources