0

I'm writing an application that awaits for a file to be copied to a folder, when the file has been copied, I then attempt the open the file.

I'm experiencing an issue where sometime the file length is zero. I believe this is because the file as not fully completed copying to the disk.

I have followed https://stackoverflow.com/a/937558/5330854 solution where I check if the file is locked, but this still allows me to open the file with the length being zero (I'd assume if the file in progress of being copied to disk, then this would be locked and I wouldn't be able to open it), when the file is not zero.

Any idea how to check if a file has finished copying to disk?

 while (stream == null && IsWithingTimeCap(startTime))
            {
                stream = GetFileStream(fileInfo);
                if (stream == null)
                {

                    Thread.Sleep(5000);

                }
    }

    if (fileInfo.Length == 0)
      {
           //log
    }


    private static Stream GetFileStream(IFileInfo fileInfo)
    {
        Stream stream = null;

        try
        {
            stream = fileInfo.Open(FileMode.Open, FileAccess.Read, 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 null;
        }

        return stream;
    }
japes Sophey
  • 487
  • 3
  • 8
  • 26
  • Thank you for taking the time to share your problem. But there is something missing from your question. What is your goal and your difficulty? What have you done so far? Please try to better explain your issue, your development environment and the data structures, as well as to share more code (no screenshot), some samples, images or sketches of the screen, and user stories or scenario diagrams. To help you improve your requests, please read the *[How do I ask a good question](https://stackoverflow.com/help/how-to-ask)* and **Questions I avoid asking** at the top right. –  Nov 04 '19 at 00:02
  • How do you *awaits for a file to be copied*? FileSystemWatcher? What is *fileInfo* and how and when do you got it? Can you put more code and the scenario sequence, please? –  Nov 04 '19 at 00:04

1 Answers1

0

A. FileSystemWatcher

You could subscribe to changes to the destination directory using FileSystemWatcher Class.

However, I don't know of an event that you could reliably to subscribe to that happens when the copying finishes. (Please also note that the Copy method returns after the last event, but this may be OK).

Here's an example.

var fileName = "a.zip";
var src = "c:\\tmp\\src";
var dst = "c:\\tmp\\dst";


using (FileSystemWatcher watcher = new FileSystemWatcher())
{
    watcher.Path = dst;

    void OnChanged(object source, FileSystemEventArgs e) =>
            Console.WriteLine($"{DateTime.Now:O}, OnChanged, file: {e.FullPath} {e.ChangeType}, size: {new System.IO.FileInfo(Path.Combine(dst,fileName)).Length}");

    void OnCreated(object source, FileSystemEventArgs e) =>
            Console.WriteLine($"{DateTime.Now:O}, OnCreated, file: {e.FullPath} {e.ChangeType}, size: {new System.IO.FileInfo(Path.Combine(dst,fileName)).Length}");


    watcher.NotifyFilter = NotifyFilters.Size
                        | NotifyFilters.DirectoryName
                        | NotifyFilters.Attributes
                        | NotifyFilters.Size
                        | NotifyFilters.LastWrite
                        | NotifyFilters.LastAccess
                        | NotifyFilters.CreationTime
                        | NotifyFilters.Security
                        ;

    watcher.Changed += OnChanged;
    watcher.Created += OnCreated;

    // Begin watching.
    watcher.EnableRaisingEvents = true;

    Console.WriteLine($"{DateTime.Now:O} Let's start copying");
    var t = Task.Run(() => {
        Console.WriteLine($"{DateTime.Now:O} Copy start");
        System.IO.File.Copy(Path.Combine(src, fileName), Path.Combine(dst,fileName), overwrite: false);
        Console.WriteLine($"{DateTime.Now:O} Copy end");
    });

    await t;

    Console.ReadLine();
}
2019-11-04T10:54:26.4737696+10:00 Let's start copying
2019-11-04T10:54:26.4972070+10:00 Copy start
2019-11-04T10:54:26.5093223+10:00, OnChanged, file: c:\tmp\dst\a.zip Changed, size: 1232583046
2019-11-04T10:54:26.5195866+10:00, OnChanged, file: c:\tmp\dst\a.zip Changed, size: 1232583046
2019-11-04T10:54:30.6444434+10:00 Copy end
2019-11-04T10:54:30.5599570+10:00, OnChanged, file: c:\tmp\dst\a.zip Changed, size: 1232583046

B. Zero length

You already have one possible answer:

I'm experiencing an issue where sometime the file length is zero.

You could check the length of the file and wait until it's not zero any more.


While this is not strictly copying, here is a view of a folder during Firefox downloading a file.

[![enter image description here][1]][1]

04/11/2019  10:01    <DIR>          .
04/11/2019  10:01    <DIR>          ..
04/11/2019  10:01                 0 SSMS-Setup-ENU.exe
04/11/2019  10:01        56,512,149 SSMS-Setup-ENU.exe.part
               2 File(s)     56,512,149 bytes

Here is a the same file being downloaded by Internet Explorer.

04/11/2019  10:04    <DIR>          .
04/11/2019  10:04    <DIR>          ..
04/11/2019  10:04                 0 SSMS-Setup-ENU.exe.pz0u92s.partial
               1 File(s)              0 bytes
tymtam
  • 31,798
  • 8
  • 86
  • 126