open file in exclusive mode in C#
Solution 1
What you are doing is the right thing. Probably you are just testing it incorrectly. You should open it with a program that locks the file when it's open. Notepad wouldn't do. You can run your application twice to see:
static void Main(string[] args)
{
// Make sure test.txt exists before running. Run this app twice to see.
File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.None);
Console.ReadKey();
}
Solution 2
Test it by writing a simple console mode program that opens the file and then waits:
static void Main(string args[])
{
using (FileStream f = File.Open("c:\\software\\code.txt", FileMode.Open, FileAccess.Read, FileShare.None))
{
Console.Write("File is open. Press Enter when done.");
Console.ReadLine();
}
}
Run that program from the command line (or another instance of Visual Studio), and then run your program. That way, you can play with different values for FileMode and FileShare to make sure that your program reacts correctly in all cases.
And, no, you don't have to check to see if the file is open first. Your code should throw an exception if the file is already open. So all you have to do is handle that exception.
Solution 3
What you have done is correct.
If you need what are all files already opened, then there is a way to see by NtQuerySystemInformation
You may get idea from http://www.codeproject.com/KB/shell/OpenedFileFinder.aspx
which gets all the files opened in a directory.. which can be extended to a single file whether opened or not...
Solution 4
I would suggest using the FileAccess.ReadWrite
member because some files may already be open but allow you Read
access on the file. However, I would guess that in non-exceptional conditions, all files open for Read/Write
access would not allow your code to Write
to the file.
Of course (as Mehrdad already explained), if you are using an editor such as Notepad to open the file as a test, you will not be able to restrict access because Notepad does not lock the file at all.
Solution 5
FileShare.None will only work if another process has also opened the file without allowing it to be shared for reads.
Programs such as Notepad and Visual Studio do not lock text files.
Ali Bagheri
Updated on July 09, 2022Comments
-
Ali Bagheri almost 2 years
I have a table.
create table tb( userid int, nodes jsonb)
nodes sample:
{ "weight": [{"date":"<date>", value: 50}, {"date":"<date>", value: 60}], "height": [{"date":"<date>", value: 170}, {"date":"<date>", value: 172}], }
I want to change the weight of a date in the list of weights.
Or enter a new value in the height list on a specific date. What should I do?
I wrote this. but it is add a new item only.
INSERT INTO tb (UserId, Nodes) values (1, '{"weight": [{"value":"50","date":"2021-07-24 18:17:33.000"}]}') ON CONFLICT (UserId) DO UPDATE SET Nodes = jsonb_set(tb.Nodes, '{"weight"}', tb.Nodes->'weight' || '{"value":"50","date":"2021-07-24 18:17:43.000"}');
I need to edit a value for a specific date.
-
Bergi almost 3 yearsHave you considered normalising your database schema instead of storing JSON?
-
Bergi almost 3 years"enter a new value in the height list on a specific date" - your current code does that already, no?
-
Ali Bagheri almost 3 yearsNo, really, this is not just my data. I wrote this for simplicity. Each user has specific information that is not the same, but all have a date field.
-
Ali Bagheri almost 3 yearsNo, I have to search between dates and edit any that have a specific date, regardless of the time
-
Bergi almost 3 yearsYou mean you want to append a new value for a date, but if an entry with that date already exists, it should be overwritten? I.e. you don't know when you need to update vs when you need to insert? Because the insertion part already works in the code you have.
-
Bergi almost 3 yearsDo you care about the order in that array?
-
-
George2 about 15 yearsThanks Jakob, anyway to check whether a file is already opened by other thread/process?
-
George2 about 15 yearsThanks Mehrdad, anyway to check whether a file is already opened by other thread/process?
-
George2 about 15 yearsThanks Cerebrus, you are correct and I am using notepad to open it and run my program to test. Any ideas to check whether a file is opened or not (for example, I want my code to be able to check whether notepad has opened it)?
-
mmx about 15 yearsI don't think there is a way to find out if a process has opened a file and is working on it. Technically, the file is no longer open after notepad loads it to memory. I think this is the right way to do it as notepad or other programs can't open it again (to read or save) which is fine, I think.
-
George2 about 15 yearsHi Jakob, my situation is, a thread is serialization (using XML serialization) to the file, another reader thread is read from this file. I do not want the reader thread to operate on this file while XML serialization is in process, any ideas?
-
George2 about 15 yearsThanks Mehrdad, I have tested you are correct. my situation is, a thread is serialization (using XML serialization) to the file, another reader thread is read from this file. I do not want the reader thread to operate on this file while XML serialization is in process, any ideas?
-
mmx about 15 yearsThis already does achieve it. You'll get IOException if a thread is reading from the file and reader threads will get IOException if they try to open the file while you are writing to it.
-
Cerebrus about 15 yearsNo, I don't think there is... except by catching the IOException in the code that tries to subsequently read the file.
-
George2 about 15 yearsHi Mehrdad, I am using XML Serialization, I am not sure if I need some special settings in order to let the serialization thread locks the file, so that the other reader thread is blocked when using FileShare.None?
-
George2 about 15 yearsMy situation is, a thread is serialization (using XML serialization) to the file, another reader thread is read from this file. I do not want the reader thread to operate on this file while XML serialization is in process, any ideas?
-
George2 about 15 yearsThanks lakshmanaraj, my situation is, a thread is serialization (using XML serialization) to the file, another reader thread is read from this file. I do not want the reader thread to operate on this file while XML serialization is in process, any ideas?
-
mmx about 15 yearsIf you want to block the thread, instead of throwing the exception, you'd better use a syncronization mechanism in your application instead of OS file locking. You could use ReaderWriterLock on a shared File object: msdn.microsoft.com/en-us/library/…
-
George2 about 15 yearsI have one thread write files with arbitrary file name, another thread read scan the dictionary to read, it is hard to predict the file name also hard to synchronize. Any comments or suggestions
-
Jakob Christensen about 15 yearsHow are you serializing? When serializing you must open the file exclusively (i.e. FileAccess.Write and FileShare.None).
-
lakshmanaraj about 15 yearsYou may lock the file or do a mutex by setting a semaphore to operation
-
George2 about 15 yearsHi Jim, my situation is, one thread is copying file (using File.Move method), and another thread is read from the file. I do not want the reader thread to read a partial of the file while copy is in process(this is why I want to have exclusive open mode), does my code posted solve this issue?
-
George2 about 15 yearsFile is very big so using RDBMS is not very efficient. (continued)
-
George2 about 15 yearsmy situation is, one thread is copying file (using File.Move method), and another thread is read from the file. I do not want the reader thread to read a partial of the file while copy is in process(this is why I want to have exclusive open mode), does my code posted solve this issue?
-
George2 about 15 yearssorry I am wrong. what I said serialization is not 100% accurate in my situation. (continue)
-
George2 about 15 yearsfile name is arbitrary so it is hard to lock. More details, I copy arbitrary files from remote machine to local machine using writer thread, and a reader thread will scan the folder and read information for new coming files
-
George2 about 15 years(continued) my situation is, one thread is copying file (using File.Move method), and another thread is read from the file. I do not want the reader thread to read a partial of the file while copy is in process(this is why I want to have exclusive open mode), does my code posted solve this issue?
-
George2 about 15 yearsmy situation is, one thread is copying file (using File.Move method), and another thread is read from the file. I do not want the reader thread to read a partial of the file while copy is in process(this is why I want to have exclusive open mode), does my code posted solve this issue?
-
Jakob Christensen about 15 yearsYes, I think your code solves it. Files are locked while being written during a copy operation so your code will not be able to read from the files during the copy operation.
-
mmx about 15 yearsIt does work in terms of not allowing two operations to be done simultaneously. The problem is that this solution does not block. It throws an exception on the thread accessing a locked file. This is why I suggest using a
lock(someObject) { }
strategy to manually sync the threads along with it. -
Jim Mischel about 15 yearsYes, your code solves that issue. It will not open the file if File.Move is in the middle of copying it.
-
lakshmanaraj about 15 yearsYes, Files are locked automatically while being written during a copy operation so your code will not be able to read from the files during the copy operation. Still you can check status(file) and struct stat->st_mode will give the share mode of the file whether it can be accessed or not.
-
Admin over 11 yearsJim, how do I know if any(!) program is opening it? Either notepad or something else. Or how do I know if it's being copied right now?
-
Jim Mischel over 11 years@Grienders: If the call to
File.Open
in this code example fails with an access violation exception, then the file is currently open from another program. You can't tell, however, if somebody is using Notepad to view the file, because Notepad opens the file, reads it into memory, and closes the file. If the file is currently being copied, the program doing the copy will have it open.