This is probably a really simple thing, but I haven't been able to find it, and I'm probably just searching for the wrong thing...
XmlTextReader --> Does it lock the file you're reading? I'm using reader.Read() and that's about it.
When you create a new XmlTextReader providing a string, it will lock the file with a write lock (but not a read lock); however, if you provide it a Stream, it would depend on the stream itself.
FileStream stream = new FileStream(#"myfile.xml", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
XmlTextReader reader = new XmlTextReader(stream);
You can now read without having a lock.
Related
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).
I want to open a file and block others from writing to it, but allow them to read it. Then after some calculations, I want to block reads as well while I write to it, so no process gets a partially written file.
However, while it seems that I can specify creation of a FileStream with either FileShare.Read or FileShare.None, I can't seem to find a way to start out with FileShare.Read and then change to FileShare.None.
The reason I don't want to create a new FileStream (with FileShare.None) is because I don't want any changes to be made to the file while I shift from the old FileStream to the new one.
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
...
}
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..
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.
I'd like to open the same file for both reading and writing. The file pointer should be independent. So a read operation should not move the write position and vice versa.
Currently, I'm using this code:
FileStream fileWrite = File.Open (path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
FileStream fileRead = File.Open (path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read);
StreamWriter _Writer = new StreamWriter (fileWrite, new ASCIIEncoding ());
StreamReader _Reader = new StreamReader (fileRead, new ASCIIEncoding ());
But that leads to an IOException: "The process cannot access the file because it is being used by another process"
I think I just figured it out myself. In the second File.Open, we're trying to deny other applications write access by specifying FileShare.Read. Instead, we need to allow the first stream to write to the file:
FileStream fileRead = File.Open (path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite);
That's inherently correct, as the reading stream should not care about other people writing to the file. At least I don't get an exception anymore.
I don't have a C# at hand, so I cannot test it.
Can't you just use FileAccess.ReadWrite instead of FileAccess.Read?
Edit: The answer is no. You need to use FileShare to do it.