gzipstream.copyto alternate and easy way in .net 3.5 - c#

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);
}

Related

C# BinaryWriter, Write with 8 bit

Im Using Binarywriter to save blob data (PDF) from oracle to disk.
The result is ugly when i open the generated file. I think its the problem of that 1 character is write with one byte.
How can i increase to write to 8. (/BitsPerComponent 8)
Any Ideas ?
long CurrentIndex = 0;
int BufferSize = 10000;
long BytesReturned;
byte[] Blob = new byte[BufferSize];
OracleDataReader reader = comando.ExecuteReader(CommandBehavior.SequentialAccess);
string filepath = "C:\\ttttt.pdf";
while (reader.Read())
{
FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(fs);
//reset the index to the beginning of the file
CurrentIndex = 0;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
while (BytesReturned == BufferSize)
{
writer.Write(Blob);
writer.Flush();
CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
}
writer.Write(Blob, 0, (int)BytesReturned);
writer.Flush();
writer.Close();
fs.Close();
}
You don't need a BinaryWriter for this. Just write to the stream directly. BinaryWriter's intended use case is writing primitive data types to a stream for serialization purposes.
Update: Automatically generate a filename from Base64(MD5(Blob)).
long CurrentIndex = 0;
int BufferSize = 10000;
long BytesReturned;
byte[] Blob = new byte[BufferSize];
using (var hasher = MD5.Create())
{
using (var reader = comando.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
var filename = Convert.ToBase64String(hasher.ComputeHash(Blob)).Replace("=", string.Empty);
var filepath = Path.ChangeExtension(Path.Combine("C:\\", filename), ".pdf");
using (var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write))
{
//reset the index to the beginning of the file
CurrentIndex = 0;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
while (BytesReturned == BufferSize)
{
fs.Write(Blob, 0, Blob.Length);
CurrentIndex += BufferSize;
BytesReturned = reader.GetBytes(0, CurrentIndex, Blob, 0, BufferSize);
}
fs.Write(Blob, 0, (int)BytesReturned);
}
}
}
}

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.

GZipStream and decompression

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))}";

Categories

Resources