Is there a limit for System.IO.FileShare?
I want to build my own flat file database. Here is how I access the flat file database
Dim fs As New System.IO.FileStream("C:\MyDb.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim sr As New System.IO.StreamReader(fs)
Is there a limit imposed by开发者_运维知识库 .Net for the usage of System.IO.FileShare.Read
, System.IO.FileShare.Write
and System.IO.FileShare.ReadWrite
when dealing with a file?
I mean is that .Net capable to support thousands of users using file stream and stream reader objects with System.IO.FileShare.Read
to access a single file concurrently?
If you try to open a file with conflicting access and share permissions it won't work. But if this is a custom database, why would you need more than one file handle open? Your custom database software should manage the open handles (having 1 per file). As for your specific question, there's no set limit, but subsequent opens of the file need to follow the rules for access and sharing permissions.
http://msdn.microsoft.com/en-us/library/aa363874%28v=vs.85%29.aspx
The FileShare
member means that other files can also open the file. This does not guarantee that data will be synchronised in any way - it simply means that multiple programs can now read (since that's what you set - FileShare.Read
) from that file while you have it open.
If you use ReadWrite
, then multiple programs can read from and write to the file. Again, you will not be notified of any changes. If multiple programs are writing to the same file at the same time as a stream, the data will be mixed together and you'll get a corrupt file. (Corrupt meaning that neither you nor the other program will be able to decompile it because your data is intertwined with your friends' application).
There are no unreasonable limitations to the number of concurrent programs reading a file.
I don't know the exact limit imposed by .NET/windows, so I have created a real test for you. I ran the following test code for few minutes and I found that up to 635908 counts of system.io.fileshare
usage, it still functional, i.e. you can still read the flat database file's content.
Here is the code (it is a winform application, .Net 4):
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim filepath As String = "c:\database.txt"
Dim filestream As System.IO.FileStream
Dim count As Int32
For count = 0 To System.Int32.MaxValue
filestream = New System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read)
AppendLog(count, filestream.ReadByte)
Next
End Sub
Private LogFilepath As String = "C:\LogInfo.txt"
Private Enter As String = Chr(13) & Chr(10)
Private Space As String = " "
Private Sub AppendLog(ByVal Sequence As Int32, ByVal info As Byte)
System.IO.File.AppendAllText(LogFilepath, Enter & Sequence & Space & CStr(info))
End Sub
End Class
Multiple objects can access a single file, however Disk on which the files is saved maintains read cache buffer for each object / process and the cache would multiply with number of objects accessing the file. The performance depends on the amount of bytes required to maintain cache per objects and total capacity of cache memory.
If file is modified when reading operation is performed then asynchronous reads should be used. however if a process terminates with part of a file locked or closes a file that has outstanding locks, the behavior is undefined.
I would recommend to explicitly destroy the stream objects when not required.
You should have only one FileStream
for writing to the file, and limit its use to one thread at a time using the usual locking mechanisms. The usual model for DBMS software is to have a concurrent queue of write operations and have a write thread that flushes them. In cases where you need the source of the write operation to await its completion, you can use an async model (BeginWrite/EndWrite).
A Semaphore
may be precisely what you need for reading, since it allows a maximum number of threads to have access to it at any point in time. You can use it to limit the disk thrashing that would occur for an unlimited number of simultaneous random reads.
However, you should ALWAYS keep a cache of the "hottest" data in memory to reduce load. Without it, your disk will just not be fast enough to keep up.
Opening a file normally means that it is opened exclusively by you and no other process can access it, unless you tell Windows you want to share it.
Setting FileShare.Read/Write means, that you grant other processes the right to read or write the file while you have it open.
I restate: You grant other processes the right to read and/or write to your file. Nothing more, nothing less.
Let's imagine the file-sharing bits as a door:
- None means, the door is closed and locked.
- Read means, you can only go one way.
- Write means, you can only go the other way.
So, what's the limit of a door?
精彩评论