将相同的文件从多个线程复制到多个目的地
本文关键字:线程 目的地 复制 文件 | 更新日期: 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#包装器。看一个更好的文件。副本替换。我不知道它是否会做你想要的(允许文件被多个线程打开),但它可能值得一试。