The process cannot access the file problem

  • (2 Pages)
  • +
  • 1
  • 2

29 Replies - 2577 Views - Last Post: 30 May 2012 - 07:01 AM Rate Topic: -----

#1 insanepenguin  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 238
  • Joined: 08-July 10

The process cannot access the file problem

Posted 28 May 2012 - 08:11 AM

Hi guys,

I've written a little utility that runs a CMD.EXE + command that writes data to a log file, then my program reads this file, splits the data into variables and inserts a record into a database, finally I truncate the log file so that repeated data isn't inserted into my database (is there another way to achieve this?). At the moment it is very hit and miss, I can get 10 - 15 records added then I receive an error: 'The process cannot access the file as it is in use by another process'

This is my timer elapsed event method that runs the command line logger
         static void myTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            
             // build a command string to change directory to and execute log2300 utility
            string command =
            string.Format(@"/c cd C:\msys\1.0\home\Administrator\open2300\ & log2300 C:\WeatherLog.txt open2300-dist.conf");

             // launch CMD.EXE and pass the command argument
            try
            {
                ProcessStartInfo cmdRun = new ProcessStartInfo();
                cmdRun.FileName = "CMD.EXE";
                cmdRun.Arguments = command;
                Process.Start(cmdRun);
                cmdRun.CreateNoWindow = true; 
               
            }
             catch(Exception Ex)
            {
                Console.WriteLine(Ex.Message);
            }


Next I pass the log file to a class that parses the data and adds to database:

static void convertData()
              /* this method creates a ParseLogFile object
                 and runs its methods to parse and insert
                 data to a database */
        {
            ParseLogFile parseData = new ParseLogFile();

            string logLocation = @"C:\WeatherLog.txt";
            try
            {
                
                parseData.ParseLog(logLocation);
               
                parseData.AddtoDatabase();
            }
            catch (Exception Ex)
            {
                Console.WriteLine(Ex.Message);
            }
        }


Next are the class methods for the parseData object

 public void ParseLog(string logFile)
            {
                this.logFile = logFile;
                // use a stream reader to open and read log file 
                using (StreamReader readLog = new StreamReader(this.logFile))
                {
                    
                    string line;
                    while ((line = readLog.ReadLine()) != null)
                    {
                        // split log string into individual data/columns

                        string[] splitData = line.Split(' ');

                        // convert split string into variables with suitable data types
                        DateTime.TryParse(splitData[1] + " " + splitData[2], out date);
                        double.TryParse(splitData[3], out indoorTemp);
                        double.TryParse(splitData[4], out outdoorTemp);
                        double.TryParse(splitData[5], out dewPoint);
                        double.TryParse(splitData[6], out rel_humidity_indoor);
                        double.TryParse(splitData[7], out rel_humidity_outdoor);
                        double.TryParse(splitData[8], out windSpeed);
                        double.TryParse(splitData[9], out windDirectionDegrees);
                        windDirectionText = splitData[10];
                        double.TryParse(splitData[11], out windChill);
                        double.TryParse(splitData[12], out rain1h);
                        double.TryParse(splitData[13], out rain24h);
                        double.TryParse(splitData[14], out totalRain);
                        double.TryParse(splitData[15], out relative_pressure);
                        tendency = splitData[16];
                        forecast = splitData[17];


                        


                    }
                }
                try
                {
                    using (FileStream f = File.Open(this.logFile, FileMode.Truncate))
                    {
                        
                        Console.WriteLine("Logfile reset");
                    }
                }
                catch (IOException iEx)
                {
                    Console.WriteLine("Problem accessing file: {0}", iEx.Message);
                }
              
            }

              public void AddtoDatabase()
             {
                  // create an SQL Server connection

                 using (SqlConnection dataConnection = new SqlConnection())
                 {
                     // build a connection string using a string builder object
                     // open a database connection
                     try
                     {
                         SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
                         builder.DataSource = "WEATHERSTATION";
                         builder.InitialCatalog = "Weather";
                         builder.IntegratedSecurity = true;
                         dataConnection.ConnectionString = builder.ConnectionString;
                         dataConnection.Open();

                     // insert record into database table

                         SqlCommand dataCommand = new SqlCommand();
                         dataCommand.Connection = dataConnection;

                         dataCommand.Parameters.AddWithValue("@date", date);
                         dataCommand.Parameters.AddWithValue("@indoor_temp", indoorTemp);
                         dataCommand.Parameters.AddWithValue("@outdoor_temp", outdoorTemp);
                         dataCommand.Parameters.AddWithValue("@dewpoint", dewPoint);
                         dataCommand.Parameters.AddWithValue("@rel_humidity_indoor", rel_humidity_indoor);
                         dataCommand.Parameters.AddWithValue("@rel_humidity_outdoor", rel_humidity_outdoor);
                         dataCommand.Parameters.AddWithValue("@wind_speed", windSpeed);
                         dataCommand.Parameters.AddWithValue("@wind_direction_degrees", windDirectionDegrees);
                         dataCommand.Parameters.AddWithValue("@wind_direction_text", windDirectionText);
                         dataCommand.Parameters.AddWithValue("@wind_chill", windChill);
                         dataCommand.Parameters.AddWithValue("@rain1h", rain1h);
                         dataCommand.Parameters.AddWithValue("@rain24h", rain24h);
                         dataCommand.Parameters.AddWithValue("@rain_total", totalRain);
                         dataCommand.Parameters.AddWithValue("@relative_pressure", relative_pressure);
                         dataCommand.Parameters.AddWithValue("@tendency", tendency);
                         dataCommand.Parameters.AddWithValue("@forecast", forecast);

                         dataCommand.CommandType = CommandType.Text;
                         dataCommand.CommandText =
                             "INSERT INTO"
                             + " dbo.WeatherData(date, indoor_temp, outdoor_temp, dewpoint," +
                                "rel_humidity_indoor, rel_humidity_outdoor, wind_speed, wind_direction_degrees," +
                                "wind_direction_text, wind_chill, rain1h, rain24h, rain_total, relative_pressure," +
                                "tendency, forecast)"

                                + "VALUES " +

                                "(@date, @indoor_temp, @outdoor_temp, @dewpoint, @rel_humidity_indoor," +
                                "@rel_humidity_outdoor, @wind_speed, @wind_direction_degrees," +
                                "@wind_direction_text, @wind_chill, @rain1h, @rain24h, @rain_total," +
                                "@relative_pressure, @tendency, @forecast)";
                         ;
                         dataCommand.ExecuteNonQuery();
                     }
                     // handle any database exceptions
                     catch (SqlException dBeX)
                     {
                         Console.WriteLine(dBeX.Message);
                     }

                 }
             }
    }


If the file access problem is down to the command line utility and the File.Truncate clashing, is there a way to only insert new records to the database instead of the entire log file each time?

Many thanks,

Mike

Is This A Good Question/Topic? 0
  • +

Replies To: The process cannot access the file problem

#2 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5574
  • View blog
  • Posts: 11,915
  • Joined: 02-June 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 08:24 AM

Quote

I receive an error: 'The process cannot access the file as it is in use by another process'


To me it sounds like you're hammering on the files faster than the code can process. This is a good example of where coding logic is easy, but making up for real-world limitations consumes so much more time. Drives are slow, networks are glitchy etc.

What about a loop to keep trying x number of times or until 10 seconds have passed? If the file hasn't become available after 10 seconds then something more serious is wrong.

DateTime bailout = DateTime.Now.AddSeconds(10);
bool success = false;
while (!success && bailout < DateTime.Now)
{
   // Try to load your file and do your thing
   success = true;
}
if (!success)
{
   // Log the failure
}

This post has been edited by tlhIn`toq: 28 May 2012 - 08:25 AM

Was This Post Helpful? 0
  • +
  • -

#3 insanepenguin  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 238
  • Joined: 08-July 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 11:42 AM

Hi tlhIn`toq,

I've been trying to apply your idea to any parts of the program that access the logfile.txt but it doesn't seem to enter the while loop:

  DateTime bailout = DateTime.Now.AddSeconds(10);
                bool success = false;
                while (!success && bailout < DateTime.Now)
                {
                    File.WriteAllText(@"C:\WeatherLog.txt", string.Empty);
                    success = true;
                    Console.WriteLine("Did this execute?");
                }
                if (!success)
                {
                    Console.WriteLine("Nope");
                }


If I remove the while loop the log file is set to an empty string but after a few inserts I get the "file in use by another process" problem again :(

Thanks
Was This Post Helpful? 0
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6076
  • View blog
  • Posts: 23,545
  • Joined: 23-August 08

Re: The process cannot access the file problem

Posted 28 May 2012 - 12:52 PM

LOGIC!

What's the time in bailout after this call?
DateTime bailout = DateTime.Now.AddSeconds(10);


What's the relationship between bailout and DateTime.Now in the line two lines following?

while (!success && bailout < DateTime.Now)


Write it down on paper if you don't get it. And where's the try/catch block?
Was This Post Helpful? 2
  • +
  • -

#5 negligible  Icon User is offline

  • D.I.C Regular

Reputation: 62
  • View blog
  • Posts: 302
  • Joined: 02-December 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 12:56 PM

Place a breakpoint on line 3 of that snippet and check which of the conditions are not being met by hovering over them with the mouse.

If it's not entering the while loop, one or both conditions are not being met. Which is it?

This post has been edited by negligible: 28 May 2012 - 12:58 PM

Was This Post Helpful? 0
  • +
  • -

#6 insanepenguin  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 238
  • Joined: 08-July 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 02:06 PM

bailout is greater than DateTime.Now when it first tests the condition, I thought the while would keep testing until .Now is greater than bailout but doesn't seem to :/
Was This Post Helpful? 0
  • +
  • -

#7 negligible  Icon User is offline

  • D.I.C Regular

Reputation: 62
  • View blog
  • Posts: 302
  • Joined: 02-December 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 02:26 PM

Okay, so bailout is greater than DateTime.Now.

Look at what Jack was saying, what does the conditional logic in the while statement say?

View PostJackOfAllTrades, on 28 May 2012 - 07:52 PM, said:

What's the relationship between bailout and DateTime.Now in the line two lines following?

while (!success && bailout < DateTime.Now)

This post has been edited by negligible: 28 May 2012 - 02:37 PM

Was This Post Helpful? 0
  • +
  • -

#8 insanepenguin  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 238
  • Joined: 08-July 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 02:40 PM

To me the logic says while success = false (as it is initially set) and DateTime bailout is less than the current time (DateTime.Now) then enter the while loop and execute the code; once this is complete set success = true; which will exit the loop.

I'm probably missing something extremely obvious! is !success making it true instead of testing that it is false?

Thanks for the help!
Was This Post Helpful? 0
  • +
  • -

#9 Viske  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 24
  • View blog
  • Posts: 70
  • Joined: 07-June 11

Re: The process cannot access the file problem

Posted 28 May 2012 - 03:08 PM

The loop is failing because bailout is greater than DateTime.Now, so bailout < DateTime.Now will always be false, so it never enters the while loop. It should be bailout > DateTime.Now.
Was This Post Helpful? 2
  • +
  • -

#10 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5574
  • View blog
  • Posts: 11,915
  • Joined: 02-June 10

Re: The process cannot access the file problem

Posted 28 May 2012 - 04:06 PM

My bad. Sorry that typo caused so much turmoil.

I my head it could have been

DateTime.Now < bailout

or

bailout > DateTime.Now

and I mashed them together with the order of one and the symbol of the either.

Bad Klingon! No rokeg blood pie for you!

Thanks Viske for putting the correct code out there.

Thanks Jack for trying to get the OP to actually think about it and reason out the mistake.
Was This Post Helpful? 0
  • +
  • -

#11 insanepenguin  Icon User is offline

  • D.I.C Head

Reputation: 7
  • View blog
  • Posts: 238
  • Joined: 08-July 10

Re: The process cannot access the file problem

Posted 29 May 2012 - 03:50 AM

Ah, I did wonder how it was going to work as bailout was always greater, DOH! I should of realised.

I tried this code:

                DateTime bailout = DateTime.Now.AddSeconds(10);
                bool success = false;
              


                    while (!success && bailout > DateTime.Now)
                    {
                        try
                        {

                            File.WriteAllText(@"C:\WeatherLog.txt", string.Empty);


                            success = true;
                            Console.WriteLine("File truncated");
                        }
                        catch(IOException iOEx)
                        {
                            Console.WriteLine(iOEx.Message);
                        }

                    }


The records are added fine and the logfile is truncated each time until around the 8th attempt, then I get the process access error and my database stops receiving new records:Posted Image

It will then stop and start intermittently, sometimes records are added and sometimes I get the error

Thanks
Was This Post Helpful? 0
  • +
  • -

#12 Viske  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 24
  • View blog
  • Posts: 70
  • Joined: 07-June 11

Re: The process cannot access the file problem

Posted 29 May 2012 - 05:10 AM

It's the same problem as previously, you're trying to access the file before it is released. I'm not sure why it's taking more than 10 seconds though.

Also, I can't see you releasing the file yourself at all. Try closing the file after you've accessed what you need to, by using .Close() on your StreamReader and FileStream objects. If it's still an issue, try timing your methods to find out how long they're taking.
Was This Post Helpful? 0
  • +
  • -

#13 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5574
  • View blog
  • Posts: 11,915
  • Joined: 02-June 10

Re: The process cannot access the file problem

Posted 29 May 2012 - 06:26 AM

The very nature of the using costruct
using( Filestream ... )
{
  ...
}


Is that you don't have to remember to .Dispose and .Close these things. That's handled for you by the framework.

That's why the OP can use the files upwards of 10 times before the error occurs.
Was This Post Helpful? 1
  • +
  • -

#14 tlhIn`toq  Icon User is online

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5574
  • View blog
  • Posts: 11,915
  • Joined: 02-June 10

Re: The process cannot access the file problem

Posted 29 May 2012 - 06:36 AM

Quote

01  static void myTimer_Elapsed


What is the interval for your timer trying to record events?
If you're throwing this every 100ms you could just have a stack of events growing faster than is possible to record.

I noticed that your log lines are every 10 seconds.

Why are you writing to the console "File has ben truncated" with every entry to the log?


Quote

04
     // build a command string to change directory to and execute log2300 utility


Log utility? Okay... Maybe I'm starting to catch up and piece this together. What log utility? I thought your program was doing it's own logging? Why would you need a seperate exe for this?

So let me see if I understand this right...

  • On the left hand you are writing to the log text file.
  • On the right hand you are passing the log text file to another exe to then open and work with...
  • And you wonder why the file is busy the next time you go to write in it?
  • Is that right?


Get rid of what ever app you have playing with the file and just do it yourself in your program.
-or-
Write in a lot more error handling for the file being locked up by the other .exe.
Was This Post Helpful? 0
  • +
  • -

#15 Viske  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 24
  • View blog
  • Posts: 70
  • Joined: 07-June 11

Re: The process cannot access the file problem

Posted 29 May 2012 - 07:11 AM

View PosttlhIn`toq, on 29 May 2012 - 02:26 PM, said:

The very nature of the using costruct
using( Filestream ... )
{
  ...
}


Is that you don't have to remember to .Dispose and .Close these things. That's handled for you by the framework.

That's why the OP can use the files upwards of 10 times before the error occurs.


Ahh, this was something I didn't know of. Thanks for clarifying.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2