I am in need of a way to write a GZipStream to a string.
I am using:
GZipStream Decompress = new GZipStream(inFile, CompressionMode.Decompress)
I have tried several methods, but can't figure it out.
Does anyone have any ideas?
Many thanks,
Brett
You have a decompressing GZipStream, so you need to read data from it. The easiest way is to wrap the GZipStream with a StreamReader which has a ReadToEnd method returning a string.
Something like:
string res;
using (var decompress = new GZipStream(inFile, CompressionMode.Decompress))
using (var sr = new StreamReader(decompress)) {
res = sr.ReadToEnd();
}
(using statements ensure that inFile is closed and any other resources are freed.)
NB this does assume that inFile contains text encoded UTF-8 or UTF-16. Binary content or other text encoding could cause problems (you can override the encoding with a different StreamReader constructor).
Related
So I'm using a streamwriter which I feed a stream, not a path. I'm not able to use a path directly, because it must take into account a mocked filesystem.
The problem with this, is that the append bool is only an option if you provide a path, not a stream.
If I do this:
using (var writer = new StreamWriter(stream, encoding))
then I can't set it to append instead of overwrite.
I've also tried to set it to the .AppendText() stream of the file, like this:
using (var writer = FileInfo.FromFileName(path).AppendText())
This works, but the problem here is that I can't set the encoding, which I need to do. I've not found a way to set the encoding after it's been constructed.
So in essence, I need a way to be able to use a streamwriter to append text, while also taking into account that I have to feed it a stream, as well as an encoding. Anyone have an idea about what I can do?
Just set the position of stream to the end before you create the StreamWriter.
stream.Position = stream.Length;
I use a webservice that returns a zip file, as a string, and not bytes as I expected. I tried to write it to the disk, but when I open it, it tells me that it is corrupt. What am I doing wrong?
string cCsv = oResponse.fileCSV;//this is the result from webservice
MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(cCsv));
using (FileStream file = new FileStream("test.zip", FileMode.Create, FileAccess.Write))
{
ms.WriteTo(file);
}
ms.Close();
I'm not sure what kind of encoding the string is in, but assuming UTF-8, the following should work. UTF-16 would be another guess.
string cCsv = oResponse.fileCSV;
using (BinaryWriter bw = new BinaryWriter(File.Create("test.zip")))
{
bw.Write(System.Text.Encoding.UTF8.GetBytes(cCsv));
}
It'd be informative to look at the characters and the raw string itself being returned.
Edit
Per Frank's answer, the correct encoding is base64, which of course makes sense because it's binary data stored as a string.
Also, per Frank's answer, if the only action is to directly write a single byte array, then File.WriteAllBytes is more compact.
Ok, i solve the problem:
File.WriteAllBytes("testbase64.zip", Convert.FromBase64String(cCsv));
I am little confused between two different constructor of StreamReader class i.e
1.StreamReader(Stream)
I know it takes stream bytes as input but the respective output is same.
here is my code using StreamReader(Stream) contructor
string filepath=#"C:\Users\Suchit\Desktop\p022_names.txt";
using(FileStream fs = new FileStream(filepath,FileMode.Open,FileAccess.Read))
{
using(StreamReader sw = new StreamReader(fs))
{
while(!sw.EndOfStream)
{
Console.WriteLine(sw.ReadLine());
}
}
}
2. StreamReader(String)
This conrtuctor takes the physical file path,
where our respective file exists but the output is again same.
Here is my code using StreamReader(String)
string filepath=#"C:\Users\Suchit\Desktop\p022_names.txt";
using (StreamReader sw = new StreamReader(filePath))
{
while(!sw.EndOfStream)
{
Console.WriteLine(sw.ReadLine());
}
}
So, Which one is better? When and where we should use respective code,
so that our code become more optimized and readable?
A class StreamReader (as well as StreamWriter) is just a wrapper for
FileStream, It needs a FileStream to read/write something to file.
So basically you have two options (ctor overloads) :
Create FileStream explicitly by yourself and wrap SR around it
Let the SR create FileStream for you
Consider this scenario :
using (FileStream fs = File.Open(#"C:\Temp\1.pb", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (StreamReader reader = new StreamReader(fs))
{
// ... read something
reader.ReadLine();
using (StreamWriter writer = new StreamWriter(fs))
{
// ... write something
writer.WriteLine("hello");
}
}
}
Both reader and writer works with the same filestream. Now if we change it to :
using (StreamReader reader = new StreamReader(#"C:\Temp\1.pb"))
{
// ... read something
reader.ReadLine();
using (StreamWriter writer = new StreamWriter(#"C:\Temp\1.pb"))
{
// ... write something
writer.WriteLine("hello");
}
}
System.IOException is thrown "The process cannot access the file C:\Temp\1.pb because it is being used by another process... This is because we try to open file with FileStream2 while we still use it in FileStream1. So generally speaking if you want to open file, perform one r/w operation and close it you're ok with StreamReader(string) overload. In case you would like to use the same FileStream for multiple operations or if by any other reason you'd like to have more control over Filestream then you should instantiate it first and pass to StreamReader(fs) .
Which one is better?
None. Both are same. As the name suggests StreamReader is used to work with streams; When you create an instance of StreamReader with "path", it will create the FileStream internally.
When and where we should use respective code
When you have the Stream upfront, use the overload which takes a Stream otherwise "path".
One advantage of using Stream overload is you can configure the FileStream as you want. For example if you're going to work with asynchronous methods, you need to open the file with asynchronous mode. If you don't then operation will not be truly asynchronous.
When at doubt don't hesitate to check the source yourself.
Note that the Stream overload doesn't take a FileStream. This allows you to read data from any sub class of Stream, which allows you to do things like read the result of a web request, read unzipped data, or read decrypted data.
Use the string path overload if you only want to read from a file and you don't need to use the FileStream for anything else. It just saves you from writing a line of code:
using (var stream = File.OpenRead(path))
using (var reader = new StreamReader(stream))
{
...
}
File.OpenText also does the same thing.
Both are same, just overloads, use one of them according to your need. If you have a local file then you can use StreamReader(string path) otherwise if you have just stream from online or some other source then other overload helps you i-e StreamReader(Stream stream)
Well after searching the new open source reference. You can see that the latter internaly expands to the former one. So passing a raw file path into the StreamReader makes him expand it internaly to a FileStream. For me this means, both are equivalent and you can use them as you prefer it.
My personal opinion is to use the latter one, because its less code to write and its more explicit. I don't like the way java is doing it with there thousand bytereader, streamreader, outputreaderreader and so on...
Basically both works same that is doing UTF8Encodeing and use Buffer of 1024 bytes.
But The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called.
You can refer the following Stream and String
You can use either of them depending on what you have in hand Stream or String file path.
Hope this makes it clear
StreamReader(string) is just an overload of StreamReader(Stream).
In the context of your question, you are probably better off using the StreamReader(string) overload, just because it means less code. StreamReader(Stream) might be minutely faster but you have to create a FileStream using the string you could have just put straight into the StreamReader, so whatever benefit you gained is lost.
Basically, StreamReader(string) is for files with static or easily mapped paths (as appears to be the case for you), while StreamReader(Stream) could be thought of as a fallback in case you have access to a file programmatically, but it's path is difficult to pin down.
If I read and wrote a binary file using StreamReader and StreamWriter, can the file be repaired?
// Original Code - Corrupted the Destination File
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (StreamWriter writer = new StreamWriter(destinationFileName, false))
{
writer.Write(reader.ReadToEnd());
}
}
}
// New Code - Destination File is Good
using (Stream responseStream = response.GetResponseStream())
{
using (FileStream fs = File.Create(destinationFileName))
{
responseStream.CopyTo(fs);
}
}
If I read and wrote a binary file using StreamReader and StreamWriter, can the file be repaired?
It depends what's in the file. If it's actually text in the right encoding, then you won't have lost anything.
If it's genuinely binary data (e.g. a JPEG) then you'll almost certainly have lost information, irreparably. Just don't do it, and if you've already done it, I probably wouldn't try to "fix" the files - I'd write them off as "bad".
If you'd used ISO-8859-1, it's possible that all would have been well - although it would still have been bad code which would be better off changed.
Try to read it with a StreamReader and see if the string you get back makes sense. This is your best option to recover the data. Once you have a "correct" string you need to try different Encodings to write to a binary file. Try UTF8, UTF16 and Encoding.Default.
I guess it will take a bit of playing around to recover some of the data. Please note that it is likely that you have lost some of it permanently.
Am I missing something or does System.IO.FileStream not read Unicode text files containing Hebrew?
public TextReader CSVReader(Stream s, Encoding enc)
{
this.stream = s;
if (!s.CanRead)
{
throw new CSVReaderException("Could not read the given CSV stream!");
}
reader = (enc != null) ? new StreamReader(s, enc) : new StreamReader(s);
}
Thanks
Jonathan
The FileStream is nothing but a byte stream, which is language/charset agnostic. You need an encoding to convert bytes into characters (including Hebrew) and back.
There are several classes to help you with that, the most important being System.Text.Encoding and System.IO.StreamReader and System.IO.StreamWriter.
The stream might be closed.
From msdn on CanRead:
If a class derived from Stream does
not support reading, calls to the
Read, ReadByte, and BeginRead methods
throw a NotSupportedException.
If the stream is closed, this property
returns false.
I'd wager that you're simply not using the right encoding. Chances are you're passing in Encoding.Default or Encoding.ASCII when you should actually be passing Encoding.UTF8 (most common) or Encoding.Unicode to that method.
If you're sure that you're using the right encoding, post the full code and an example of the file.