How to decompress with GZipStream in C#? - c#

My problem is that I can't find a solution to decompress a file. Compressing a file works without error messages, but I don't know if that's right.
Here is my code for compressing a file:
using (StreamReader sr = new StreamReader(File.Open(srcFile, FileMode.Open), true))
using (GZipStream zip = new GZipStream(File.Open(destFile, FileMode.OpenOrCreate), CompressionMode.Compress, false))
using (StreamWriter sw = new StreamWriter(zip, Encoding.UTF8)) {
while (!sr.EndOfStream) {
sw.Write((char)sr.Read());
}
}
Then I tried to decompress the compressed file with following code:
using (GZipStream zip = new GZipStream(File.Open(srcFile, FileMode.Open), CompressionMode.Decompress, false))
using (StreamReader sr = new StreamReader(zip, true))
using (StreamWriter sw = new StreamWriter(File.Open(destFile, FileMode.OpenOrCreate), Encoding.UTF8)) {
while (!sr.EndOfStream) {
sw.Write((char)sr.Read());
}
}
The content of the decompressed file wasn't like the content of the source file and I don't know where I've made my mistakes.
Thanks in advance for your help.
I'm sorry for my bad English, but English isn't my strength. :/

Using StreamReader/Writer is not indicated. It will certainly destroy the file content if the file is not a text file. And the decompressed file will always have a BOM, it might be missing in the original file.
There's just no reason to use these classes, GZipStream doesn't care. Use FileStream instead, the only way to be sure that the decompressed bytes are an exact match with the bytes in the original file.

Related

Downloading mail attachments damaging files

i'm using C# to download the attachments on a mail message but all the files I download is damaged (specially PDF files), the code I;m using only download one attachment at the time (because are being moved based on criteria)
The code I'm using:
byte[] allBytes = new byte[item.ContentStream.Length];
int bytesRead = item.ContentStream.Read(allBytes, 0, (int)item.ContentStream.Length);
string destinationFile = #Destination;
BinaryWriter writer = new BinaryWriter(new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None));
writer.Write(allBytes);
writer.Close();
BinaryWriter is only meant to write primitive data to a file. It's not meant for stream operations. You can copy data from one stream to another with Stream.CopyTo eg:
using(var targetStream=new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
{
item.ContentStream.CopyTo(targetStream);
}
Don't use BinaryWriter. You already have the binary content, just write that to disk.
File.WriteAllBytes(destinationFile, allBytes)

ArgumentException in StreamWriter in Xamarin.Forms

I am writing a Xamarin.Form PLC for Android and iOS, and have a place where I need to write some application stuff to a text file embedded resource. I've implemented reading from the same text file successfully, with same syntax just using StreamReader, but the StreamWriter implementation looks like this:
Assembly assembly = GetType().GetTypeInfo().Assembly;
string resource = "jetStream.Results.settings.txt";
using (Stream stream = assembly.GetManifestResourceStream(resource)) {
using (StreamWriter writer = new StreamWriter(stream)) {
//do stuff
}
}
StreamWriter is throwing an argument of "Stream is not writeable" at System.IO.StreamWriter. Am I doing something obvsiously wrong? Why is the Stream Readable but not Writeable using the same assembly/resource/stream construction?
The stream from GetManifestResourceStream is not writable. The stream's file is embedded in the assembly at build time and cannot be changed. You'll have to write the file to disk before you can write to it.
string resource = "jetStream.Results.settings.txt";
using (Stream stream = assembly.GetManifestResourceStream(resource))
using (var fs = new FileStream(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal)), FileMode.Create, FileAccess.Write))
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(fs))
{
rStream.Stream.CopyTo(stream);
writer.Write(stream.ToArray());
}
After this you can read and write to the file on disk.
Depending on what you want to write, if it's just things like application settings, you can use the Application.Properties collection http://www.kymphillpotts.com/exploring-xamarin-forms-1-3-properties-dictionary/ otherwise I agree with Jon's answer.

Overwriting file in c# using stream writer

I am trying to write a html file using stream writer in c#, it is overwriting the file if close the application and run again, but its appending when I tried to write file for different scenario without closing the application. I wants to overwrite in second case also.
using (FileStream fs = new FileStream("Report.html", FileMode.Create, FileAccess.Write))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.WriteLine(html);
}
}
To append to the end of your file:
File.AppendAllText("Report.html", html, Encoding.UTF8);
To overwrite your file:
File.WriteAllText("Report.html", html, Encoding.UTF8);
Try explicitly closing the writer and stream instead of depending upon you using () expression to do that for you.

unable to save dynamically created MemoryStream with rebex sftp

I'm using StreamWriter to generate a dynamic file and holding it in a MemoryStream. Everything appears to be alright until I go to save the file using rebex sftp.
The example they give on their site works fine:
// upload a text using a MemoryStream
string message = "Hello from Rebex FTP for .NET!";
byte[] data = System.Text.Encoding.Default.GetBytes(message);
System.IO.MemoryStream ms = new System.IO.MemoryStream(data);
client.PutFile(ms, "message.txt");
However the code below does not:
using (var stream = new MemoryStream())
{
using (var writer = new StreamWriter(stream))
{
writer.AutoFlush = true;
writer.Write("test");
}
client.PutFile(stream, "test.txt");
}
The file "test.txt" is saved, however it is empty. Do I need to do more than just enable AutoFlush for this to work?
After writing to the MemoryStream, the stream is positioned at the end. The PutFile method reads from the current position to the end. That's exactly 0 bytes.
You need to position the stream at the beginning before passing it to PutFile:
...
}
stream.Seek(0, SeekOrigin.Begin);
client.PutFile(stream, "test.txt");
You may also need to prevent the StreamWriter from disposing the MemoryStream:
var writer = new StreamWriter(stream);
writer.Write("test");
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
client.PutFile(stream, "test.txt");

iTextSharp + FileStream = Corrupt PDF file

I am trying to create a pdf file with iTextSharp. My attempt writes the content of the pdf to a MemoryStream so I can write the result both into file and a database BLOB. The file gets created, has a size of about 21kB and it looks like a pdf when opend with Notepad++. But my PDF viewer says it's currupted.
Here is a little code snippet (only tries to write to a file, not to a database):
Document myDocument = new Document();
MemoryStream myMemoryStream = new MemoryStream();
PdfWriter myPDFWriter = PdfWriter.GetInstance(myDocument, myMemoryStream);
myDocument.Open();
// Content of the pdf gets inserted here
using (FileStream fs = File.Create("D:\\...\\aTestFile.pdf"))
{
myMemoryStream.WriteTo(fs);
}
myMemoryStream.Close();
Where is the mistake I make?
Thank you,
Norbert
I think your problem was that you weren't properly adding content to your PDF. This is done through the Document.Add() method and you finish up by calling Document.Close().
When you call Document.Close() however, your MemoryStream also closes so you won't be able to write it to your FileStream as you have. You can get around this by storing the content of your MemoryStream to a byte array.
The following code snippet works for me:
using (MemoryStream myMemoryStream = new MemoryStream()) {
Document myDocument = new Document();
PdfWriter myPDFWriter = PdfWriter.GetInstance(myDocument, myMemoryStream);
myDocument.Open();
// Add to content to your PDF here...
myDocument.Add(new Paragraph("I hope this works for you."));
// We're done adding stuff to our PDF.
myDocument.Close();
byte[] content = myMemoryStream.ToArray();
// Write out PDF from memory stream.
using (FileStream fs = File.Create("aTestFile.pdf")) {
fs.Write(content, 0, (int)content.Length);
}
}
I had similar issue. My file gets downloaded but the file size will be 13Bytes. I resolved the issue when I used binary writer to write my file
byte[] bytes = new byte[0];
//pass in your API response into the bytes initialized
using (StreamWriter streamWriter = new StreamWriter(FilePath, true))
{
BinaryWriter binaryWriter = new BinaryWriter(streamWriter.BaseStream);
binaryWriter.Write(bytes);
}
Just some thoughts - what happens if you replace the memory stream with a file stream? Does this give you the result you need? This will at least tell you where the problem could be.
If this does work, how do the files differ (in size and binary representation)?
Just a guess, but have you tried seeking to the beginning of the memory stream before writing?
myMemoryStream.Seek(0, SeekOrigin.Begin);
Try double checking your code that manipulates the PDF with iText. Make sure you're calling the appropriate EndText method of any PdfContentByte objects, and make sure you call myDocument.Close() before writing the file to disk. Those are things I've had problems with in the past when generating PDFs with iTextSharp.
documentobject.Close();
using (FileStream fs = System.IO.File.Create(path)){
Memorystreamobject.WriteTo(fs);
}

Categories