I have a method which saves the object into the file. The object gets modified and saved multiple times. The problem is that when I'm trying to save object for the second time into the same file, I'm getting the UnautorizedAccessException. Here is the code:
public void Save(string path)
{
string fileName = String.Format("{0}\\{1}", path, DataFileName);
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fs, this);
File.SetAttributes(fileName, FileAttributes.Hidden);
}
}
What's the most interesting, is that if I comment the line
File.SetAttributes(fileName, FileAttributes.Hidden);
problem disappears. How comes? And how can I solve this problem?
MSDN says this about FileMode.Create:
Specifies that the operating system should create a new file. If the
file already exists, it will be overwritten. This requires
FileIOPermissionAccess.Write permission. FileMode.Create is equivalent
to requesting that if the file does not exist, use CreateNew;
otherwise, use Truncate. If the file already exists but is a hidden
file, an UnauthorizedAccessException exception is thrown.
Which is exactly what you are seeing. So the solution seems to be either use a different mode, or as suggested in the comments, unhide -> save -> hide.
Related
(C#) I get an out-of-memory crash when I try setting the image of a "picture box" with one opened from a file.
My code:
string file = openImageBox.Text; // Our file
if (File.Exists(file))
{
File.Open(file, FileMode.Open); // Open the file for use.
Output.Text = "File Open Success!"; //Informing the user on how sucessful they are.
Output.ForeColor = System.Drawing.Color.Black;
Image img = Image.FromFile(file);
Display.Image = img;
}
Probably not the right answer (who knows.. it could be causing you all sorts of issues).
You don't need to "Open the file for use". This is holding a handle to the file you don't need. Just call Image.FromFile directly and it will work fine.
So remove this:
File.Open(file, FileMode.Open); // Open the file for use.
EDIT:
For completeness (and to help you learn), you need to store a reference to the stream if you want to close it. What I told you to remove above holds a handle to the file. The file is essentially open now.. until you close it.
For other code (where you're not using a method like Image.FromFile), you would either store a handle to the file so you can close it.. or use a using statement to close it for you.
Option A:
var stream = File.Open(file, FileMode.Open);
// do stuff here
stream.Close();
Option B (preferred):
using (var stream = File.Open(file, FileMode.Open)) {
// do stuff here
} // stream.Close automatically called for you
I have a log file of my application, I do some manipulation by sided application on the log file.
At the end of the manipulation, I want to delete the file - which is not possible becuase file is used, so I just want to empty it - delete the contents.
I tried:
using (FileStream stream = File.Open(query.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
using (StreamWriter writer = new StreamWriter(stream, true))
{
writer.Write("");
reader.Close();
}
}
and:
using (FileStream stream = File.Open(query.FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
stream.SetLength(0);
stream.Close();
}
and:
System.IO.File.WriteAllText(#"path", string.Empty);
Notihg works.
How to overrride file content?
Not at all. It will crash, because file is being used by another process
Well, it probably isn't another process, it probably is yours. You'll have to do this after closing the log file. But there's a more general fix for that. Go back to the code that creates the log file and add the FileShare.Delete option.
This option allows deleting files that are in use. You can now simply use File.Delete() in your code, even if the log file is still opened. This will put the file in a "delete pending" state, anybody that tries to open it will be slapped with an access denied error. The file on the disk will automatically disappear when the last handle to the file is closed.
Yet another useful option is FileOptions.DeleteOnClose. Now it is completely automatic, the file is automatically deleted without you having to do anything at all. I can't tell which one is best in your case, you probably want to avoid deleting the log file when your program crashed so FileShare.Delete is best.
You can use the below code too
System.IO.File.WriteAllText(#"Path of your file",string.Empty);
I am making a level editor for my game, and most of it is working except...
When I try to save my file (XML) the file doesn't get created, and in the output box I get:
A first chance exception of type 'System.NullReferenceException'
The funny thing is that it only happens if the file doesn't exist, but it works correctly if I overwrite another file.
here is the code I'm using:
using (StreamWriter stream = new StreamWriter(filePath))
{
stream.Write(data);
stream.Close();
}
data is a string (this is not the problem because it works when I overwrite the file)
You're missing a constructor which takes a boolean that can aid in creating the file:
using (StreamWriter stream = new StreamWriter(filePath, false)) {
stream.Write(data);
stream.Close();
}
The logic is actually is little more complex than that, however:
public StreamWriter(
string path,
bool append
)
Determines whether data is to be appended to the file. If the file
exists and append is false, the file is overwritten. If the file
exists and append is true, the data is appended to the file.
Otherwise, a new file is created.
Why don't you just go around it the easy way, and check for file existence prior to writing to it:
public void Foo(string path, string data)
{
if (!File.Exists(path))
File.Create(path);
using (var sw = new StreamWriter(path, false))
{
// Work your magic.
sw.Write();
}
}
I'd really not make it any more complicated than that personally. Also, don't close the StreamWriter, the using statement disposes of it after it's served its purpose.
In my case I was running the program as non-admin, the file was to be written inside a folder that was created with administrator rights (even inside ProgramFiles or any non-admin location). The file is never created and you have to manually enable the Managed Debugging Assistants exception breaks in order to see any error.
Solution was to delete the folder and create it again with my non-admin account. Also note that StreamWriter does not create directory trees, only files.
Have you tried not using File.Create()? like so:
using (StreamWriter stream = new StreamWriter(filePath)) {
stream.Write(data);
stream.Close();
}
I'm writing code that check files path calculate hash (SHA1) and copy them.
I made sure that I do not lock them like for example using
public static string SHA1(string filePath)
{
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var formatted = string.Empty;
using (var sha1 = new SHA1Managed())
{
byte[] hash = sha1.ComputeHash(fs);
foreach (byte b in hash)
{
formatted += b.ToString("X2");
}
}
return formatted;
}
So how I can, in Visual Studio, find where it does lock the file?
Can you keep the above syntax as and give a try?
using(var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
//Your code goes here.
}
There is a little windows soft : process explorer and in this you can find which process has an handle on a file :
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Locking usually happens whenever you create a file stream on a file without later closing that stream. Unless you call fs.Close(); in your code, your application will keep the file open (and thus locked).
You could wrap this in a try-finally block or try the code that Siva Gopal posted.
You assumption that opening the file stream with just FileAccess.Read will not lock the file is faulty; the file is locked while it has been opened for a file operation and has not been closed.
A FileStream does not close an opened file until the FileStream is garbage collected or you explicitly call its Close or Dispose method. Either insert such an explicit call as soon as you are done with the file you opened, Or wrap the use of the FileStream in a using statement, which implies the call to Dispose, like other answers suggest.
I am getting binary data from a SQL Server database field and am creating a document locally in a directory my application has permissions. However I am still getting the error specified in the title. I have tried numerous suggestions posted on the web including those suggested in previous posts on Stackoverflow. I have also used ProcessExplorer > Find Handle to locate the lock and it returns nothing as if the file is not locked.
I am using the code below to save the file to the file system and I then try to copy this file to a new location later in the application process within another method. It is this copy method that takes the path of the newly created file that throws the exception.
The file itself is created with its content and i can open it through Windows Explorer without any problems.
Am I missing something completely obvious? Am I creating the file correctly from the database? Any help on solving or better diagnosing the problem would be much appreciated.
// Get file from DB
FileStream fs = new FileStream(
"C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
fs.Flush();
fs.Close();
fs.Dispose();
// Copy file
File.Copy(sourceFileName, destinationFilename, true);
Try adding a call to GC.Collect() after you have disposed of your streams to force the garbage collector to clean up.
// Get file from DB
using(FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write))
using(BinaryWriter br = new BinaryWriter(fs))
{
br.Write("BinaryDataFromDB");
fs.Flush();
}
//Force clean up
GC.Collect();
// Copy file
File.Copy(sourceFileName, destinationFilename, true);
change your code as follows, the problem is that the the filestream isn't being garbage collected when you need it to:
// Get file from DB
using (FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write))
{
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
fs.Flush();
fs.Close();
}
// Copy file
File.Copy(sourceFileName, destinationFilename, true);
What about using?
string source = #"C:\myTempDirectory\myFile.doc";
using(FileStream fs = new FileStream(
source, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read))
{
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
}
File.Copy(sourceFileName, destinationFilename, true);
EDIT: Try to inform a FileShare.Read permission.
I came to understand that though the error debugger says that the error lies in this code.. But that isn't where the error is..
I faced a similar issue and I came with this solution.. consider all the posts above..
May be it may help some one..
I used the Image to show it in a picturebox after retreiving from Database and saving it as "temp.bmp" using normal coding without using "using" keyword using this code at first:
PictureBox1.Image = Image.FromFile("temp.bmp");
and it raised and error and I really didn't got head and tail of the error.. and so I came up with this solution.
Instead of assigning it directly try this code:
Bitmap img;
using (Bitmap bmp = new Bitmap("temp.bmp"))
{
img = new Bitmap(bmp);
}
pictureBox1.Image = img;
coming to the filestream part I just used normal code as follows:
FileStream fs = new FileStream("filepath",FileMode.Create);
and it worked like a piece of cake
It really helped
Is it that Filestream and BinaryWriter cannot be used at the same time? For instance, a streamwriter and a streamreader cannot both be called on the same file. However, this doesn't make sense, as far as I know, it should not in this case. Perhaps try closing br as well?
Try disposing your BinaryWriter object before doing the copy.
Is there a background process such as antivirus or file-system indexing locking the file just long enough to cause problems with your application? Try pausing for 3 seconds to see if your problem disappears.
using System.Threading;
fs.Dispose();
Thread.Sleep(3000);
// Copy file
This was what I did:
Stream stream = new MemoryStream();
var tempStream = new FileStream(pathToFile, FileMode.Open);
tempStream.CopyTo(stream);
tempStream.Close();
then use stream object wherever you want.
I seem to encounter this only after I have published an application. If you close the message box and try again to debug, nothing will happen.
MS Help says to get all the way out of Visual Studio and restart it. Its easier to bring up Task manager and end the process. Its name will be the solution name followed by ".vshost" (e.g. project name: PLC.sln; process name: PLC.vshost.exe). The process will restart automatically. In Windows 7 one could usually see something happen when ending a process. But in 10 the Task Manager window rarely changes.
I get this message when I try testing a program after changing code. Apparently the .exe is not closed when one stops debugging and the error occurs when VS tries to write a newly complied exe file. I sometimes have to end the process twice to keep the error message from coming back. (I have to encounter the error twice; ending the process twice and then rerunning doesn't help.)
This is a bug in Visual Studio.