I am trying to make a tagging solution for .wav audiofiles.
For that reason I need to open the file to read out it's Tags.
The code for that starts out like this:
this.Reader = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read));
this.RiffId = Encoding.ASCII.GetString(Reader.ReadBytes(4)); // excluding 8 bit header
this.FileSize = Reader.ReadInt32(); // size of entire file (4 bytes)
this.FileType = Encoding.ASCII.GetString(Reader.ReadBytes(4));
From my understanding, this will open the File readonly normally? However, when I open the audio file while it is open in my application, media players spit out an error stating that the file is beeing blocked by my program:
I whish to have the file readonly, writing will always be a full Copy of the file.
Having the possibility to read the file in two programs at a time is necessary when listening to the audio in order to tag the file.
Closing the file while listening to it is not so easily possible as I want to keep my application responsive. Additional data from the riff chunks is loaded and stored in buffer when nessesary only.
this.Reader = new BinaryReader(File.Open(path,FileMode.Open,FileAccess.Read,FileShare.Read));
FileMode.Open specifies, how to proceed with the file. More on that on https://learn.microsoft.com/en-us/dotnet/api/system.io.filemode?view=net-5.0
some examples:
Open 3
Specifies that the operating system should open an existing file. The ability to open the file is dependent on the value specified by the FileAccess enumeration. A FileNotFoundException exception is thrown if the file does not exist.
Append 6
Opens the file if it exists and seeks to the end of the file, or creates a new file. This requires Append permission. FileMode.Append can be used only in conjunction with FileAccess.Write. Trying to seek to a position before the end of the file throws an IOException exception, and any attempt to read fails and throws a NotSupportedException exception.
Truncate 5
Specifies that the operating system should open an existing file. When the file is opened, it should be truncated so that its size is zero bytes. This requires Write permission. Attempts to read from a file opened with FileMode.Truncate cause an ArgumentException exception.
FileAccess specifies your own file access
https://learn.microsoft.com/en-us/dotnet/api/system.io.fileaccess?view=net-5.0
FileShare specifies the access other threads have to the file
https://learn.microsoft.com/en-us/dotnet/api/system.io.fileshare?view=net-5.0
Related
So I have this WinForms EXE (VS2010) which reads and writes from / to a single XML file like this:
// read
FileStream dbXmlFileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
myDataSet.ReadXml(dbXmlFileStream);
dbXmlFileStream.Close();
// write
myDataSet.AcceptChanges();
StreamWriter xmlSW = new StreamWriter(path);
myDataSet.WriteXml(xmlSW, XmlWriteMode.IgnoreSchema);
xmlSW.Close();
The XML file lives on a networked drive and is shared by multiple instances of the same EXE (also on the same networked path). So each user has a shortcut on their machine pointing to the same EXE.
Whoever accesses the EXE first ("first" as in the 1st EXE instance running) should get exclusive write access to the XML. Subsequent EXE instances should be able to read (i.e. throw no errors when opening the EXE) but get a locking error when trying to save into the same XML via their EXE instance.
With my code, there are no exceptions thrown while multiple users read or write into the file. However, it's misleading because in the case where all of them attempted to save something at the same time, only the most recent save persists on the disk.
How can I remove ambiguity and actually capture write lock exceptions for any subsequent users?
I tried different variations of FileAccess and FileShare enums in File.Open with no luck.
I am having a spot of bother trying to save a dummy file to the nul device in an ASP.Net (.Net 4.5.2) application. When I get the the point where the application tries to save the file, it throws an exception.
The file's path is set to "nul" (sic), and when it is saved I get the following exception message:
Access denied to file "\\\\.\\nul"
Is it possible using .Net (C# in my case) to save a file to the nul device from within a web application?
In case you are wondering, saving the file is merely a trigger for another action. I am not interested in the saved file itself, and I want to avoid the code overhead of having to create and later delete a uniquely named dummy file - hence saving it to the nul device.
TIA
This answer on MSDN suggests you can't do this with the .NET file handling API:
While the Win32 CreateFile method will open devices, alternate streams, etc, somewhere along the line it was decided that the .Net File implementation would be restricted to traditional files. Probably not what you wanted to hear.
social.msdn.microsoft.com/Forums/vstudio/en-US/43163abb-4e82-4a7d-b614-29eb7914bdba/nul-filename-in-net
use the flag that deletes filestream on close...
new FileStream(TempFileName,
FileMode.CreateNew,
FileAccess.ReadWrite,
FileShare.ReadWrite, 512,
FileOptions.DeleteOnClose);
I am coding in C# for the first time and encountering this.
I use the function File.WriteAllBytes(OutputFileName, dest); which is creating a file on the disk and when my application tries to open the same file using file.Open giving me an exception Access to Path Denied. Please help me to get rid of this. I am on Windows 7, not running as administrator.
Thank you.
The file is closed. It is denied for other reasons. Check the path, or maybe you could open it with FileMode File.Open(path, FileMode.Open). Otherwise check your permissions.
Given a byte array and a file path, this method opens the specified file, writes the contents of the byte array to the file, and then closes the file.
Source
The method WriteAllBytes closes the file after writing the byte array to the file so I guess your problem lies elsewhere.
Definition:
Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.
More reading on the method: File.WriteAllBytes Method
Robert was ahead of me.. :)
A couple of things spring to mind:
Where are you saving the file to? Windows 7 seems to picky about saving to the root of C:\ these days.
Permissions issue.
Is there any way to determine if a file is open by anything include applications that do not lock the file (like notepad).
I need to detect when a given file myfile.txt is no longer open in any application including notepad - so i cannot use File.Open(...) with exclusive access to test since the file has no lock on it.
No. When Notepad has opened a file, it has read the entire file in and then closed it. So there is no trace in the OS that links Notepad's private memory with the file on disk.
Opening the file exclusively will not work, because Notepad does not have the file open. Searching Notepad's handle table will not work, because Notepad does not have the file open.
The only way to detect this is to write an unmanaged DLL that is injected into every process to scan their virtual memory, searching for the exact file contents. Not recommended.
You must call File.Open(...) specifying your desired access flags and check the returning value to determine if the file is opened or if the access is denied. This is the recommended and safe way to access a file.
I am trying to figure out how to write a binary file with a FileStream and BinaryWriter, and keep the file locked for read while I am writing. I specifically don't want other applications/processes to be able to read from the while while its being written to.
//code to declare ba as a byte array
//dpath is the path to the file
FileStream BinaryFile = new FileStream(dpath, FileMode.Create, FileAccess.Write);
BinaryWriter Writer = new BinaryWriter(BinaryFile);
Writer.Write(ba);
Writer.Close();
BinaryFile.Dispose();
Now the problem is the file can be opened by other applications during the write, which is undesirable in my current application. The FileStream has a Lock Method, but that locks for writing and not for reading, so that doesn't help me.
You're looking for the fourth parameter of the FileStream Constructor.
public FileStream(
string path,
FileMode mode,
FileAccess access,
FileShare share
)
So in your case:
FileStream BinaryFile = new FileStream(dpath, FileMode.Create,
FileAccess.Write, FileShare.None);
FileShare-Enum:
Contains constants for controlling the kind of access other FileStream
objects can have to the same file.
Members:
None, Declines sharing of the current file. Any request to open the file (by this process or another process) will fail until the file is closed.
Read, Allows subsequent opening of the file for reading. If this flag is not specified, any request to open the file for reading (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.
Write, Allows subsequent opening of the file for writing. If this flag is not specified, any request to open the file for writing (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.
ReadWrite, Allows subsequent opening of the file for reading or writing. If this flag is not specified, any request to open the file for reading or writing (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.
Delete, Allows subsequent deleting of a file.
Inheritable, Makes the file handle inheritable by child processes. This is not directly supported by Win32.
I don't know if it is possible.
For instance Firefox stores files while downloading using another name until they are finished. When everything is there, it renames it to the original name. A different file suffix will avoid that users try to open it with a double click.