Link to home
Start Free TrialLog in
Avatar of klay8
klay8

asked on

write to file

hi
i am writing a function writing to a file every one second, i get this error:
An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file 'c:\users\mohamad\documents\visual studio 2005\projects\save to file\debug\file3.txt' because it is being used by another process.
THANKS

private: System::Void timer2_Tick(System::Object^  sender, System::EventArgs^  e) 
{DateTime		^now = System::DateTime::Now;
file2 = gcnew StreamWriter(System::AppDomain::CurrentDomain->BaseDirectory+"file3.txt");
MessageBox::Show(now->ToString());
 file2->Write(now->ToString());
 file2->Close();  
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Alexandre Simões
Alexandre Simões
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
instead use:

 my.computer.filesystem.writealltext

josgood: I considered the messagebox was there just by mistake for some test... it's essential thar a repetitive task that occurs every one second doesn't have any user interaction :)

Dauhee: that's VB and the man's code is C++ :)


Cheers!
OK.  Understood on why you didn't mention the MessageBox.  

I did a short test, using a 0.1 second timer with the MessageBox removed, and there was no problem.

If more data was being written, I could agree with the idea that more time is required.  With a write this short, however, I don't see a problem on modern hardware.
I don't know if the whole provided code was a mere example... is it just
file2->Write(now->ToString());

the real scenario? or is this just a sample code that wasn't well done?

Is this writing to a local drive or using a remote path?
How many process write/read to this file?
Can it be opened directly by a user?

All questions must be answered and in either case I think an "escape plan" right on the begginig of the method is in order to act as a safety net if the file is exclusively opened by another process...

Like "they" say... s**t happens :)
These are all good questions.

I concur on the safety net.
>>>> The process cannot access the file 'c:\users\mohamad\documents\visual studio 2005\projects\save to file\debug\file3.txt' because it is being used by another process.

Do you have any idea what the second process is?

you didn't look at the file in the Visual Studio or another text editor?

Generally, if you open an existing file for write, it is truncated to zero size. That only works, if the file wasn't opened for write in a second program.

>>>> file2 = gcnew StreamWriter(System::AppDomain::CurrentDomain->BaseDirectory+"file3.txt");
You better split that statement into two. First build teh filename as a string. Then create a new StreamWriter object passing that string. Doing so, you can check whether the built filepath is valid in the Debugger. You also cancheck whether you can delete the 'existing' file using Windows Explorer and/or the command window. If you can't do it from there, it is clear that it wouldn't work programmatically either. Last, you could put the 'open' statement into a try catch block and handle the exception rather than let it crash.

The process that is locking your file is the one that runs that code you've posted...

The first tick goes correctly but after one second another tick calls the same code but the file is still exclusively opened by the previous tick.
>>>> The first tick goes correctly but after one second another tick
>>>> calls the same code but the file is still exclusively opened by the previous tick.
No. While the timer handler was running there is no further timer action. Windows timers either were invoked by a message pump which calls timer handlers asynchronously but not in a separate thread.  And system timers have one timer handle which changes between signaled or non-signaled. While your are handling a timer event you must not fear that the same timer will be triggered again as long as you don't establish such a behavior yourself.
Yeah... I think you're right...
I've done a little test and dropped the ticking interval to 1 millisecond and it works fine, no problems writing to a file.

Still there's no problem setting UI controls properties which means that it runs on the same thread than the UI.
The only way I was able to crack this was opening the file from the explorer wile the timer was running.
Avatar of klay8
klay8

ASKER

hi i resolved by this:

My guess is that 1 second is too little time to this task.
If the StreamWriter is still open when the method is called again this exception will occur.

Try making it 5 or 10 seconds just to test it out.

My advise is that you evaluate the state of the stream right on the beginning of the method.
Declare the StreamWriter outside of the method so there's only one instance of it at a time, at the beginning of the method evaluate if it's open, if so exit, will try again on the next second.

for now it's ok for me,
but i am interested about what u said all of u

thanks