0

I am using c# for FTP file upload using this code

while(true)
{
    if(condition == true)
    {
        Process[] proc = Process.GetProcessName("ThirdPartyApp");
        if(proc.Length <0 )
        {
            var file = Process.GetProcess().Where(pr=>pr.ProcessName == "ThirdPartyApp")
            foreach(var process in file)
            {
                process.kill(); // Third party application stopped
            }
            if(File.Exists(filename))
            {
               using (System.Net.WebClient client = new System.Net.WebClient())
               {
                 client.Credentials = new System.Net.NetworkCredential("username", "password");
                 client.UploadFile(ftpServer  + new FileInfo(filename).Name, "STOR", filename);
               }
               File.Delete(filename);
               Process.Start("ThirdPartyApp");
            }
       }
    }
}

My program continuously runs. At a specified time, it uploads a file to the server. After my program starts, it uploads the file successfully to the server at first time, but at another time interval, at the second time, it gives this exception.

I dont understand why it is giving error at the first loop run, but why it is giving error at the second time in loop.

The process cannot access the file 'E:\TYV.csv' because it is being used by another process.

After deleting the file, a new file immediately gets created. At the second run, which process is using that file? Is it my own application ?

Why it is not locked at the first time ?

Thanks

Harshit
  • 5,147
  • 9
  • 46
  • 93
  • Is the file that is being complained about on the client or on the server? – Lasse V. Karlsen Jul 10 '15 at 07:55
  • It is on the client which I am sending it on the server. A third party application is creating it. Before uploading, I kill third party application then upload, then again starts the third party application. – Harshit Jul 10 '15 at 07:57
  • If you can access the server you can use unlocker to see which process is locking the file. http://filehippo.com/download_unlocker/. But I'd put my money on that it is your application. – Eric Herlitz Jul 10 '15 at 07:57
  • Why are you are using `while(true)`? Try to place the upload code in different method rather than in while loop and use Timer instead of of while loop with always true. – NASSER Jul 10 '15 at 07:58
  • I am not allowed to upload any software on the server. This problem is coming at the server only not on my system. Timer also having the same problem. – Harshit Jul 10 '15 at 08:00

1 Answers1

1

Changing the looping, as suggested in the comments, will not result if the file is locked. For sure your app is locking the file. This can mean that you are trying to upload the file before ts is released by the third party, or before the writing to it is finished (this can happen with buffered IO).

If you don't have access to the third party app to check what it is doing (and change it if necessary), you can do something like this:

This first routine checks if the file is locked (taken from here: Is there a way to check if a file is in use?

//routine to check if the file is locked
protected virtual bool IsFileLocked(FileInfo file)
{
    FileStream stream = null;

    try
    {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException)
    {
        //the file is unavailable because it is:
        //still being written to
        //or being processed by another thread
        //or does not exist (has already been processed)
        return true;
    }
    finally
    {
        if (stream != null)
            stream.Close();
    }

    //file is not locked
    return false;
}

public void SendFile(string filename, int maxTries)
{
    bool done;
    while(true)
    {
        if(condition == true)
        {
            if(!IsFileLocked(filename))
            {
                Process[] processes = Process.GetProcessByName("ThirdPartyApp");
                foreach (var proc in processes)
                    proc.Kill();

                using (System.Net.WebClient client = new System.Net.WebClient())
                {
                    client.Credentials = new System.Net.NetworkCredential("username", "password");
                    int count = 0;
                    done = false;
                    while (count < maxTries || !done)
                    {
                        try
                        {
                            client.UploadFile(ftpServer  + new FileInfo(filename).Name, "STOR", filename);
                            done = true;
                        }
                        catch(Exception ex)
                        {
                            System.Threading.Thread.Sleep(5000);
                            count++;
                        }
                    }
                    if (!done)
                    {
                        //handle the error
                    }
                }

                File.Delete(filename);
                Process.Start("ThirdPartyApp");
            }
        }
    }
}

If it is a problem of a temporary locker, this can help you to solve it. But be warned that if you kill the third party before it releases the file, and the File.Exist can give you the false impression that the process finished it's job, you will still get a lock in the file.

Another point is the the Check to see if the file is locked can also fail, if just after the check the "ThirdPartyApp" locks the file and you kill the app before the app releases it.

So, to me the best answer is to use thsi code and try to open the file (locking it yourself). If this is possible (no exception), send to FTP using the opened stream.After finish, close it, delete the file and run the ThirdApp again.

EDIT: Add code to see if the file is locked and only if not delete the ThirdPartyApp and after this to execute the rest of the code.

Community
  • 1
  • 1
Jauch
  • 1,500
  • 9
  • 19
  • I have edited my code above, showing the actual code. As said, I am killing the ThirdPartyApp before uploading the file to the server. Also, the time is running every second i.e the looping is executed every second. – Harshit Jul 10 '15 at 09:07
  • As I said, killing the process that creates the file you are trying to upload has a very high risk of turn the file locked if the process is killed before the file is ready or before the app releases the file. The frequency with this is done (1 second) will improve even more these possibility. – Jauch Jul 10 '15 at 11:46
  • OK, then why it doesnt lock the file when first run of the loop but only after first run i.e. running 2nd or 3rd time the same code, it gives the exception. If goes on your logic, then it should give problem at the first run also!!!!! – Harshit Jul 13 '15 at 03:04
  • Not necessarily. There are a number of reasons for this to happen. For example: at the first time, the file is already there, because the ThirdPartApp was already running and had finish it's job when your app starts, and the second time, it is processing the file when you simply kill it. Also I noticed that you kill the app BEFORE you check if the file exists. I'll edit my answer to provide you with some "insight" on how to verify that you can do what you want (send the file to the to the FTP). – Jauch Jul 13 '15 at 08:34
  • Please, see my last comments on the answer. I really think you should open the file and send the stream to the FTP. Open it will rise an exception if it is locked, and than you simply ignore and try again on the next cycle. If it opens, it will lock the file (use the right mode) and you can than kill the app, as the file will be on your control. – Jauch Jul 13 '15 at 08:57
  • I added `System.Threading.Thread.Sleep(3000);` after `process.kill();` statement & also added `GC.Collect();` before `using (System.Net.WebClient client = new System.Net.WebClient())`. Now my code is working fine. It is now not showing any problem. Thanks for the replies. – Harshit Jul 13 '15 at 10:09
  • Glad you solve the issue. :) This question is intriguing. I'll do some tests on my own (when I have time ;) rs) to understand the question better :) – Jauch Jul 13 '15 at 13:28
  • It seems you were right. I was immediately uploading the file after killing the third party app process & it was having a handle on the logs file. After Adding sleep of 3 seconds it is working fine. Thanks for your solutions. – Harshit Jul 14 '15 at 03:17