Ado
Ado

Reputation: 47

How to test in C# if a new file has been completely moved to a folder?

I’ve programmed a Windows utility that watches a folder for changes (it triggers when a new file is added to the folder) and it basically compresses every PDF it receives in that folder.

It worked wonderfully until yesterday. Someone moved a PDF into that compression folder, but that person had a very slow internet connection and the PDF was large. My PDF compressor utility got triggered before the PDF was completely moved, and as you can guess, not so many good things happened.

I did not try anything. First, I want to know if you guys have a better idea. My solution was to fix it like this (I don’t think it’s optimal, that’s why I am writing here):

After my program gets triggered when a file moves into the compression folder, it checks if the added file is a PDF. When it’s a PDF, it should try to open it and if it fails it waits for 2 minutes and opens it again. If it does not work, it just ignores the current PDF (because it can be a corrupt PDF and my compressor program is single-threaded and should watch for other PDFs).

bool pdfFreeToUse = false;
try {
    byte[] readPdf = File.ReadAllBytes(PdfPath);
    pdfFreeToUse = true;
}
catch
{
    using (System.Timers.Timer setTimer = new System.Timers.Timer(Double.Parse(Config.ConfigExtractor("GhostRestartAfterMillisecond"))))
    {
        setTimer.AutoReset = false;
        setTimer.Start();
        setTimer.Elapsed += (sender, e) =>
        {
            try
            {
            byte[] readPdf = File.ReadAllBytes(PdfPath);
            pdfFreeToUse = true;
            } catch
            {
                //creates an Eventlog in Eventviewer under Applicationlog in there is none and writes the error there
                string ErrorMessage = $"Auf die PDF {PdfName} kann nicht zugegriffen werden, da sie möglicherweise von einem anderen Prozess verwendet wird oder beschädigt ist.";
                EventProtocol.CreateEventLog();
                EventProtocol.WriteErrorEventLog(ErrorMessage);
                WriteErrorAsTxt(PdfPath + $@"\" + PdfName + "_Error.txt", ErrorMessage);
            }
        };
        setTimer.Stop();
    }
}
if (pdfFreeToUse)
{
    //do nothing 
} else
{
    //stops the program flow in current function
    return;
}

//The rest of the code to compress Pdf

Upvotes: 0

Views: 75

Answers (1)

vhr
vhr

Reputation: 1664

You can use FileSystemWatcher to detect when a file is copied into your folder:

When you copy a file or directory, the system raises a Created event in the directory to which the file was copied, if that directory is being watched.

Then you can use this method to detect if a file copy has finished.

You would basically run a e.g. 'DetectFileCopyFinished' task each time you receive 'FileSystemWatcher.Created Event'. And then run your compress PDF logic

Upvotes: 0

Related Questions