Suppose you have this:
using FileStream fileStream = ...;
fileStream.Write(bytes);
using GZipStream gzipStream = new GZipStream(fileStream, CompressionLevel.Optimal);
gzipStream.Write(bytesToCompress);
Would writing to fileStream first, and then creating a new GZipStream from that stream and then writing bytes to it work?
Do I have to flush fileStream first? Or is this simply unsafe?
Would writing to fileStream first, and then creating a new GZipStream from that stream and then writing bytes to it work?
Yes, that is sort of the point of streams really, that they are chainable. See Compose streams.
Do I have to flush fileStream first? Or is this simply unsafe?
Flush is only necessary when you wish to purge buffers and guarantee that the data are written to the backing store (e.g. the filesystem or network).
Related
I am calling REST API which is accepting Stream to upload file from local device, so for that right now I am using following code to get Stream from a file and than closing that stream after it get's uploaded:
var stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
The problem with the above approach is that, until entire file gets uploaded to server user don't have any chance to delete that file because stream of that file is open, what would be the solution to resolve this issue?
If your typical file is reasonably sized (and I'm hoping you won't be uploading 2GB+ files to a REST API), you could always just read the stream into memory and before feeding it to your API, like so:
using (MemoryStream memoryStream = new MemoryStream())
{
using (FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite)) {
fileStream.CopyTo(memoryStream);
}
memoryStream.Position = 0; // Reset to origin.
// Now use the MemoryStream as you would a FileStream:
api.Upload(memoryStream);
}
Another alternative is to create a temp copy of the file on your hard drive and feed that to the API - but then dealing with cleanup can become a bit cumbersome. FileOptions.DeleteOnClose is your friend and may very well suffice for your purposes, but it still offers no bulletproof guarantees.
In some code for writing and reading a file first create FileStream object then pass it as an argument to StreamWrite or StreamReader, my question is why they don't just creat StreamWrite or StreamReader ? and does each StreamWrite or StreamReader create FileStream automatically ?
FileStream output=new FileStream(fileName,FileMode.OpenOrCreate,FileAccess.Write);
StreamWriter fileWriter=new StreamWriter(output)
Thanks a lot
You're right, it is possible to instantiate a SteamWriter directly with a FilePath and a FileStream will be created automatically under the hood.
But remember that a StreamWriter is an object that is able to write to any Stream (not just FileStreams); the convenience constructor of creating a FileStream underneath the hood is normally good enough. But if someone has some special need to open up a FileStream with very specific options set, they will first create the FileStream, then pass it to the StreamWriter.
If you want to write or read a file you can use the File class.
File.ReadAllText(path);
File.WriteAllText(path,txt);
File.ReadAllLines(path);
File.WriteAllLines(path,lineArray);
No need to use FileStream..
To answer your question of why StreamWriter and StreamReader need to be passed a FileStream..
So that StreamWriter and StreamReader could be reused..
readStream(new FileStream(path,FileMode.Open));//read file stream
readStream(new NetworkStream(url));//read newtwork stream
readStream(new MemoryStream(object));//read memory stream
public void readStream(StreamReader sr)//general reader method
{
//read stream
}
This method is so general it could read almost any stream thereby reusing the code..
i want to write the data in file and also read it to display simultaneously from the same in C#.
how to do this ?
var fs = new System.IO.FileStream(fileName, System.IO.FileAccess.ReadWrite);
and then you can call
long oldPos = fs.Position;
fs.Write(....);
fs.Flush();
fs.Position = oldPos;
fs.Read(...);
Flush after writing and read it afterwards.
By the way, why don't display it from memory?
You can open a FileStream for both reading and writing. For example:
byte[] writeBuffer; // Contains data to write
byte[] readBuffer; // Large enough space to read data
FileStream fileStream = new FileStream("file.txt",
FileMode.OpenOrCreate, FileAccess.ReadAndWrite);
fileStream.Write(writeBuffer, 0, writeBuffer.Length);
fileStream.Seek(0, SeekOrigin.Begin);
fileStream.Read(readBuffer, 0, readBuffer.Length);
You can use the same object to do reads and writes. However, doing both simultaneously requires careful coordination in your application to prevent the operations interfering with each other. A better solution might be to queue the operations.
I have a function that is returning MemoryStream array, i want to convert this memory stream array to a FileStream object.
Is it possible if yes can you please provide a way to do that...
Thanks
A.S
You cannot "convert" the stream, because a MemoryStream and a FileStream are very different things. However, you can write the entire contents of the MemoryStream to a file. There is a CopyTo method that you can use for that:
// memStream is the MemoryStream
using (var output = File.Create(filename)) {
memStream.CopyTo(output);
}
A file stream object represents an open file (from disk) as a stream. A memory stream represents an area of memory (byte array) as a stream. So you can't really convert a memory stream into a file stream directly - at least not trivially.
There are two approaches you could take:
OFFLINE: fully consume the contents of the memory stream and write it all out to a file on disk; then open that file as a file stream
ONLINE: extent the FileStream class creating an adapter that will wrap a MemoryStream object and expose it as a FileStream (essentially acting as a converter)
The reason one is marked [OFFLINE] is because you need to have to full contents of the memory stream before you output it to the file (and once you do, modifications to the file stream will not affect the memory stream; nor changes to the memory stream, such as new data, be available to the file stream)
The second one is marked as [ONLINE] because once you create the adapter and you initialize the FileStream object from the MemoryStream you could process any new data in the MemoryStream using the FileStream adapter object. You would essentially be able to read/write and seek into the memory stream using the file stream as a layer on top of the memory stream. Presumably, that's what you'd want to do..
Of course, it depends on what you need to do, but I'm leaning towards the second [ONLINE] version as the better in the general sense.
FileStream fs = new FileStream("Myfile.Txt",FileMode.Open,FileAccess.Read);
StreamReader sr= new Streamreader(fs);
sr.BaseStream.Seek(0,SeekOrigin.Begin);
In this Code What is the use of BaseStream in this Code.?
Seek is Method ,
sr is an Object of Class StreamReader
then What is BaseStream
sr.BaseStream returns the underlying stream where the stream reader reads from, you can use this to operate directly on the stream.
In your sample sr.BaseStream and the FileStream fs are the same thing.
More info: http://msdn.microsoft.com/en-us/library/system.io.streamreader.basestream.aspx
Usually though you would like to work with the StreamReader itself, because this abstracts away some of the difficulties when working with streams. If you give an example how you would like to use the stream then I can see if I can give a possibly easier sample using StreamReader
You could have shortened your code:
//FileStream fs = new FileStream("Myfile.Txt",FileMode.Open,FileAccess.Read);
//StreamReader sr= new Streamreader(fs);
StreamReader sr = File.OpenText("Myfile.Txt"); // using-block omitted
sr.BaseStream.Seek(0,SeekOrigin.Begin);
And then you can't use fs anymore. There still is a Stream being created, and BaseStream gives you access.
And note you should be careful to flush the Reader before Seeking on the Stream.