将同一文件从多个线程复制到多个目标

时间:2013-06-20 19:53:10

标签: c# .net multithreading file-io

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

更新: 如果这只是一个失败的原因,我愿意采取其他方法来完成这项工作。我的最终目标是尽可能快地将同一文件复制到数据中心的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);
}

4 个答案:

答案 0 :(得分:2)

神奇的词是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);
            }
        }
    }

然后你应该能够复制它,即使有多个线程。

答案 1 :(得分:2)

另一种解决方法是将文件缓存在内存中....

类似

  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]));

答案 2 :(得分:0)

如果您未指定COPY_FILE_OPEN_SOURCE_FOR_WRITE标记,则可以通过调用CopyFileEx来执行此操作。

几年前我为CopyFileEx发布了一个C#包装器。见A better File.Copy replacement。我不知道它是否会做你想要的(允许多个线程打开文件),但它可能值得一试。

答案 3 :(得分:0)

好的,所以在经历了一个非常沮丧的夜晚之后,似乎我需要一些睡眠来解决这个问题。

我最初在按钮点击事件中做了我的foreach,因为我在那个foreach中开始了一个线程,它只是继续而不管其他一切的状态。我已经把那个foreach移到了线程上,问题就解决了。我现在可以立即复制到多个位置,我必须说它非常快。

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