将相同的文件从多个线程复制到多个目的地

本文关键字:线程 目的地 复制 文件 | 更新日期: 2023-09-27 18:19:21

我正在尝试编写一个应用程序,该应用程序将我创建的安装程序复制到提供的计算机列表中。在输入中只有一个计算机名时它工作得很好,但是当我添加两个或更多计算机名时,它告诉我它无法从源文件中读取,因为它正在使用。

更新:如果这件事注定要失败,我愿意接受其他方法。我的最终目标是尽可能快地将相同的文件复制到数据中心的500台计算机上。然后在每台计算机上执行该文件。现在对于执行,我使用psexec -s,所以我可以绕过UAC。

/*Button Click Code Below*/
/*Install for specific OS*/
foreach (string line in txtServers.Lines)
{
    machine = line;
    lbOutput.Items.Add("Preparing to copy files....");
    /*Copy Files*/
    if(!tWorker.IsAlive)
         tWorker.Start();
    lbOutput.Items.Add("File Copy Complete! Executing installer....");
}
/*File Copy Code Below*/
try
{
   File.Copy("Ionic.Zip.Reduced.dll",@"''"+machine+@"'C$'Temp'Ionic.Zip.Reduced.dll",true);
   File.Copy("v5.32bit.Install.exe", @"''" + machine + @"'C$'Temp'v5.32bit.Install.exe", true);
}
catch (Exception ee)
{
   MessageBox.Show(ee.Message);
}

将相同的文件从多个线程复制到多个目的地

这个神奇的词是FileShare.Read:

  using(var inputFile = new FileStream(
         "oldFileName.txt", 
         FileMode.Open, 
         FileAccess.Read, 
         FileShare.Read))
     {
        using (var outputFile = new FileStream("newFileName.txt", FileMode.Create))
        { 
            var buffer = new byte[0x10000];
            int bytes;
            while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0) 
            {
                outputFile.Write(buffer, 0, bytes);
            }
        }
    }

那么你应该能够复制它,即使有多个线程

另一种方法是将文件缓存到内存中....

比如

  var filesToLoad = new[] {"a.txt", "b.txt"}.ToList();
  var files = new Dictionary<string, byte[]>();
  filesToLoad.ForEach(f => files.Add(f, File.ReadAllBytes(f)))

然后当你想写它们时

files.Keys.ToList()
   .ForEach(f => File.WriteAllBytes(Path.Combine(machinePath, f), files[f]));

好吧,经过一个晚上的强烈挫折,我似乎只是需要一些睡眠来解决这个问题。

我最初在按钮单击事件中完成了我的foreach,因为我在该foreach中启动了一个线程,它只是继续不管其他一切的状态。此后,我将该foreach移到了线程中,问题得到了解决。我现在可以一次复制到多个位置,我必须说它非常快。

感谢大家一如既往的帮助!

如果您没有指定COPY_FILE_OPEN_SOURCE_FOR_WRITE标志,您可以通过调用CopyFileEx来完成此操作。

几年前我为CopyFileEx发布了一个c#包装器。看一个更好的文件。副本替换。我不知道它是否会做你想要的(允许文件被多个线程打开),但它可能值得一试。