Streamwriter crashes when writing to existing file - c#

Here is the code I have that writes to a couple of files:
StreamWriter writer = new StreamWriter(#"C:\TotalStock\data\points\" + stockName.ToUpper() + ".txt");
for(int i = 0; i < lines; i++)
{
writer.WriteLine(lineData[i]);
postGui.Send((object state) =>
{
progressBar2.PerformStep();
}, null);
}
writer.Close();
When I delete the text files and run the code there is no issue, but then when I close the application and run it once more the program gives me the following error. What is it that causes this error and what can I do to stop it?
Error:
An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll
Additional information: The process cannot access the file 'C:\TotalStock\data\points\IBM.txt' because it is being used by another process

As marc_s pointed out, the error occurs because the file you are trying to edit is opened by another application. If you are certain that you don't have the file opened in any other editor/viewer, the problem may the program itself.
If several instances of the same code run concurrently and require access to the same file, say in a multithread environement.
Does another component in your application read from the text file while you are trying to write to the file?
Does your application hang, and the second instance requires the same file?
Do you run the same tests each time?

Probably the problem is that you open the file but do not close it when you exit the program. i see you are using StreamWriter to write the data to the file.
might by you get an exception and therefor does not close the file. when playing with files you should always do:
try
{
// Your code with files
}
catch
{
}
finally
{
writer.Close();
}
other reasons might be that you are using some other File/Stream/etc. please be sure that you close all the members that need to be closed before close the program.
please share all your code if you want us to check if you forgot something else
as Sayse Is saying another way to make sure you close your writers is a using statement:
using(StreamWriter writer = new StreamWriter(#"C:\TotalStock\data\points\" + stockName.ToUpper() + ".txt");)
{
// Your code of playing with files
}

Related

System.IO.File.Delete throws "The process cannot access the file because it is being used by another process"

Every time I save a file and delete it right away using the function below, I keep getting this error message: "System.IO.IOException: The process cannot access the file because it is being used by another process".
Waiting for a couple of minutes or closing visual studio seems to only unlock the files that you uploaded previously.
public static bool DeleteFiles(List<String> paths)
{ // Returns true on success
try
{
foreach (var path in paths)
{
if (File.Exists(HostingEnvironment.MapPath("~") + path))
File.Delete(HostingEnvironment.MapPath("~") + path);
}
}
catch (Exception ex)
{
return false;
}
return true;
}
I think that the way I'm saving the files may cause them to be locked. This is the code for saving the file:
if (FileUploadCtrl.HasFile)
{
filePath = Server.MapPath("~") + "/Files/" + FileUploadCtrl.FileName;
FileUploadCtrl.SaveAs(filePath)
}
When looking for an answer I've seen someone say that you need to close the streamReader but from what I understand the SaveAs method closes and disposes automatically so I really have no idea whats causing this
After some testing, I found the problem. turns out I forgot about a function I made that was called every time I saved a media file. the function returned the duration of the file and used NAudio.Wave.WaveFileReader and NAudio.Wave.Mp3FileReader methods which I forgot to close after I called them
I fixed these issues by putting those methods inside of a using statement
Here is the working function:
public static int GetMediaFileDuration(string filePath)
{
filePath = HostingEnvironment.MapPath("~") + filePath;
if (Path.GetExtension(filePath) == ".wav")
using (WaveFileReader reader = new WaveFileReader(filePath))
return Convert.ToInt32(reader.TotalTime.TotalSeconds);
else if(Path.GetExtension(filePath) == ".mp3")
using (Mp3FileReader reader = new Mp3FileReader(filePath))
return Convert.ToInt32(reader.TotalTime.TotalSeconds);
return 0;
}
The moral of the story is, to check if you are opening the file anywhere else in your project
I think that the problem is not about streamReader in here.
When you run the program, your program runs in a specific folder. Basically, That folder is locked by your program. In that case, when you close the program, it will be unlocked.
To fix the issue, I would suggest to write/delete/update to different folder.
Another solution could be to check file readOnly attribute and change this attribute which explained in here
Last solution could be using different users. What I mean is that, if you create a file with different user which not admin, you can delete with Admin user. However, I would definitely not go with this solution cuz it is too tricky to manage different users if you are not advance windows user.

Dispose slow on very big filestreams?

I've got this code
string archiveFileName = BuildArchiveFileName(i, null);
string tmpArchiveFileName = BuildArchiveFileName(i, "tmp");
try
{
using (FileStream tmpArchiveMemoryStream = new FileStream(tmpArchiveFileName, FileMode.Create))
{
using (BinaryWriter pakWriter = new BinaryWriter(tmpArchiveMemoryStream))
{
if (i == 0)
{
WriteHeader(pakWriter, pakInfo.Header);
WriteFileInfo(pakWriter, pakInfo.FileList);
uint remainingBytesToDataOffset = pakInfo.Header.DataSectionOffset - CalculateHeaderBlockSize(pakInfo.Header);
pakWriter.Write(Util.CreatePaddingByteArray((int)remainingBytesToDataOffset));
}
foreach (String file in pakInfo.FileList.Keys)
{
DosPak.Model.FileInfo info = pakInfo.FileList[file];
if (info.IndexArchiveFile == i)
{
//Console.WriteLine("Writing " + file);
byte[] fileData = GetFileAsStream(file, false);
int paddingSize = (int)CalculateFullByteBlockSize((uint)fileData.Length) - fileData.Length;
pakWriter.Write(fileData);
pakWriter.Write(Util.CreatePaddingByteArray(paddingSize));
}
}
}
}
}
finally
{
File.Delete(archiveFileName);
File.Move(tmpArchiveFileName, archiveFileName);
}
I've tested this with NUnit on small file sizes and it works perfectly. Then when I tried it on a real life example , that are files over 1 GB. I get in trouble on the delete. It states the file is still in use by another process. While it shouldn't that file should have been disposed of after exiting the using branch. So I'm wondering if the dispose of the filestream is slow to execute and that is the reason I'm getting in trouble. Small note in all my file handling I use a FileStream with the using keyword.
While it shouldn't that file should have been disposed of after exiting the using branch
That's not what it is complaining about, you can't delete archiveFileName. Some other process has the file opened, just as the exception message says. If you have no idea what process that might be then start killing them off one-by-one with Task Manager's Processes tab. That being your own process is not entirely unusual btw. Best way is with SysInternals' Handle utility, it can show you the process name.
Deleting files is in general a perilous adventure on a multi-tasking operating system, always non-zero odds that some other process is interested in the file as well. They ought to open the file with FileShare.Delete but that's often overlooked.
The safest way to do this is with File.Replace(). The 3rd argument, the backup filename, is crucial, it allows the file to be renamed and continue to exist so that other process can continue to use it. You should try to delete that backup file at the start of your code. If that doesn't succeed then File.Replace() cannot work either. But do check that it isn't a bug in your program first, run the Handle utility.

File.Delete fails silently - how to debug?

The following code fails to delete the file and prints file delete: so I know the file exists. With my app open I am able to delete the file in file explorer.
How can I debug this?
1) File permissions? My app created the file so should be able to delete? Regardless it would throw an exception and hit my catch debug message.
2) The file exists! According to the docs any other failure besides non-existence should be caught in my catch...
if (File.Exists(fn))
{
Debug.WriteLine("file delete: " + fn);
try
{
File.Delete(fn);
}
catch
{
Debug.WriteLine("Could not delete: " + fn);
}
} else {
Debug.WriteLine("File doesn't exist: "+fn);
}
The file is saved from a RichTextBox using the following code if this matters.
TextRange range;
FileStream fStream;
range = new TextRange(mNotepad.Document.ContentStart, mNotepad.Document.ContentEnd);
fStream = new FileStream(fn, FileMode.Create);
range.Save(fStream, DataFormats.XamlPackage);
fStream.Close();
Deleting a file does not provide a guarantee that the file will actually be removed from the file system. The file might have been opened by another process, which explicitly specified delete sharing. Very similar to read and write sharing. Also available in .NET, you'd pass FileShare.Delete to the FileStream constructor.
But the physical file can of course not be removed until all processes close the file. So it lingers beyond the File.Delete() call, can be seen by File.Exists() as well. Opening the file can no longer work, that will be rejected with access denied. Otherwise an excellent reason to never use File.Exists(), it has many problems.
If you want to find out what other process has the file opened then you can use a utility like SysInternals' Handle or Process Explorer. Expect to find back a program like a virus scanner or search indexer, could be anything however. Like a .NET program :)
From MSDN:
If the file to be deleted does not exist, no exception is thrown.
Make sure your path exists. I know you said you did, but check again.
Make sure you reach the actual File.Delete line
Cheers
I had the same issue before, follow the steps to see if it helps you. As silly as it may sound. Make sure no processes other than yours are making use of that file you created? Is this application multi-threaded? Do you have services running that use the file?
Make sure your not in debug mode, and do a Build - Clean
Check that the file is still at the location and copy the file path.
Put a break point right before file deletion.
Rebuild your project after you put your break-point.
Press F5 to debug and step through the code.
Check that the file path matches the one that you have.
I tried to reproduce similar situation with my own code
string fn = #"C:\Users\Public\Pictures\Sample Pictures\Desert - Copy.jpg";
//The file is locked by Image.FromFile
Image img = Image.FromFile(fn);
//If img.Dispose() here, then file is unlocked and can be deleted
if (File.Exists(fn))
{
try
{
File.Delete(fn);
Debug.WriteLine("file delete: " + fn);
}
catch
{
//Caught
Debug.WriteLine("Could not delete: " + fn);
}
}
else
{
Debug.WriteLine("File doesn't exist: " + fn);
}
I found the file is locked by Image.FromFile() and therefore Could not delete.
For the same reason, I believe your file with path fn is locked by the Filestream ftream
Can you try to do
fStream.Dispose();
before your delete process and rerun the program to see if you can delete the file? thanks. You can dispose the fstream and create a new one if needed,right?

what process is preventing my file from getting deleted in C#

I have a C# single thread application that creates a file. Uses that file and then deletes it. Some times the app has trouble deleting that file. The error I get is:
"The process cannot access the file --file path and file name-- because it is being used by another process."
How can I find out what process has a hold on this file and how can I make that process to let go so that the file can be deleted.
This thing rocks for that very "gotcha".
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
Process Monitor v3.05
It has a "Filter" submenu so you can fine tune it to the file that is locked.
You need to post the relevant code so we can see.
It is however always important to make sure that your app close the file that it has opened.
usually something like this will ensure that:
using(var f = File.OpenRead("myfile")) {
...
}
or the equivalent:
try {
var f = File.OpenRead("myfile");
} finally {
f.close()
}
Make sure that you are closing file before delete.
if you are using StreamWriter class make sure that you are closing with its variable
Ex. StreamWriter sw = new StreamWriter();
// some writing operation
sw.Close();

Exception trying to write a LogFile using FileStream and StreamWriter

So basically I write a windows service that scans any given directory for a zip file and then uploads it to an FTP server. I added a tracing method that suppose to write into a txt file and keep a log of everything. The problems comes when I release the service into windows I get a error message in the Event Viewer( I added a LogEvent using EventLog class) that returns
System.IO.IOException: The process cannot access the file
'C:\Windows\system32\traceLog.txt' because it is being used by another
process.
The code that does the tracing is the following
private void EscribirTrace(string mensaje)
{
if (Tracing)
{
try
{
using (FileStream archivo2 = new FileStream(string.Format("{0}\\traceLog.txt", Environment.CurrentDirectory), FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
{
mensaje = string.Format("{0} - {1} \r\n", DateTime.Now, mensaje);
StreamWriter writer = new StreamWriter(archivo2);
writer.WriteLine(mensaje);
writer.Flush();
writer.Dispose();
}
}
catch (Exception ex)
{
LogEvent("Error en escribir tracing", ex);
}
}
}
Any ideas would be appreciated
Edit So after some research I figure that that system32 is not the best place for the file. My intention was to have that log file at the path were the service was installed. After some research I replaced the
Enviroment.CurrentDirectory
for
Path.GetFullPath(System.Reflection.Assembly.GetExecutingAssembly().Location).Replace(
Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().Location)
Formated into a string.
The rest just worked pretty well.
Thank you for the responses !
Its because your using statement has not released the file yet. You have it open in the steam so you can't write to it until you close your stream.
If you want to simply write text to a file just use:
File.WriteAllText(FILEPATH, TEXTDATA);
That call will open the file, write to it, and then close it.
if it throws on the using ...make sure all other streams on the file are closed properly ...
if it throws on the streamwriter constructor
change the using to be the stream writer with the new filestream in the constructor
/Windows/system32 requires admin access. Your application probably isn't running with the proper privileges. You should try writing the log to a different (less restrictive) location. If you need to write to system32 ensure that your service is running with admin privileges.

Categories

Resources