2013-06-20 34 views
2

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

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

回答

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

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

+0

我不认为使用FileShare.ReadWrite是正确的方式。如果他正在将文件复制到多台计算机上,则在复制完成之前不应允许进行更改。改为使用FileShare.Read。 –

+0

@SGrimminck:谢谢你的建议。我相应地改变了它。 –

+0

仍然得到该进程无法访问文件“文件名”,因为它正在被另一个进程使用。这个异常来自上面第二段代码中的try/catch,并且实现了您的更改。例外情况是显示远程路径。 –

0

你可能会能够通过调用CopyFileEx要做到这一点,如果你不指定COPY_FILE_OPEN_SOURCE_FOR_WRITE标志。

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

0

好吧,在经历了一个强烈的挫折之夜之后,我似乎需要一些睡眠来解决这个问题。

我原本是在按钮单击事件中完成我的foreach,并且由于我在该foreach中启动了一个线程,所以无论其他任何状态如何,它都会继续。自那以后,我把这个foreach转移到了线程上,问题解决了。我现在可以一次复制到多个位置,我必须说它非常快。

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

相关问题