C#-仅在文件已完全复制到磁盘时复制文件

我正在编写一个应用程序,等待将文件复制到文件夹,复制完文件后,然后尝试打开文件。

我遇到一个文件长度为零的问题。我相信这是因为文件没有完全完成复制到磁盘。

我遵循了https://stackoverflow.com/a/937558/5330854解决方案,其中检查了文件是否被锁定,但这仍然允许我打开长度为零的文件(我假设是否正在将文件复制到磁盘上) ,那么当文件不为零时,它将被锁定,而我将无法打开它)。

有什么主意如何检查文件是否已完成复制到磁盘吗?

 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;
    }
f2003365964y 回答:C#-仅在文件已完全复制到磁盘时复制文件

A。 FileSystemWatcher

您可以使用FileSystemWatcher Class订阅对目标目录的更改。

但是,我不知道您可以可靠地订阅的事件在复制完成时发生。 (还请注意,Copy方法在上一个事件之后返回,但这可能是可以的。)

这是一个例子。

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,OnCreated,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,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,file: c:\tmp\dst\a.zip Changed,size: 1232583046
2019-11-04T10:54:26.5195866+10:00,size: 1232583046
2019-11-04T10:54:30.6444434+10:00 Copy end
2019-11-04T10:54:30.5599570+10:00,size: 1232583046

B。零长度

您已经有一个可能的答案:

  

我遇到一个文件长度为零的问题。

您可以检查文件的长度,然后等待它不再为零。


虽然这不是严格复制,但这是Firefox下载文件期间的文件夹视图。

[![在此处输入图片描述] [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,149 bytes

这是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
本文链接:https://www.f2er.com/3169792.html

大家都在问