下面是我的代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.IO.MemoryMappedFiles;
namespace CopyFile
{
class Program
{
static void Main()
{
long length = 0;
byte[] buffer;
string source_path, dest_path;
source_path = Console.ReadLine();
dest_path = Console.ReadLine();
FileInfo fi = new FileInfo(source_path);
length = (int)fi.Length;
// Create disk file
using (FileStream fs = File.Create(dest_path))
{
fs.Close();
}
// Create unnamed MMF
var mmf1 = MemoryMappedFile.CreateFromFile(source_path, FileMode.OpenOrCreate, null, length);
// Create reader to MMF
var reader = mmf1.CreateViewAccessor(0, length, MemoryMappedFileAccess.Read);
// Create unnamed MMF
var mmf2 = MemoryMappedFile.CreateFromFile(dest_path, FileMode.Create, null, length);
// Create writer to MMF
var writer = mmf2.CreateViewAccessor(0, length, MemoryMappedFileAccess.Write);
int read_block = int.Parse(Math.Min(length, 512 * 1024).ToString());//4k
int end_read_block = int.Parse(length.ToString()) % read_block;
int[] offset_array = new int[int.Parse((length - read_block).ToString()) / read_block];
for (int offset = 0,i=0; i < int.Parse((length - read_block).ToString()) / read_block; i++,offset += read_block)
{
offset_array[i] = offset;
}
/*
Parallel.ForEach<int>(offset_array, offset =>
{
// Read from MMF
buffer = new byte[read_block];
reader.ReadArray<byte>(offset, buffer, 0, read_block);
// Write to MMF
writer.WriteArray<byte>(offset, buffer, 0, read_block);
});
*/
foreach (int offset in offset_array)
{
// Read from MMF
buffer = new byte[read_block];
reader.ReadArray<byte>(offset, buffer, 0, read_block);
// Write to MMF
writer.WriteArray<byte>(offset, buffer, 0, read_block);
}
buffer = new byte[end_read_block];
reader.ReadArray<byte>(length - end_read_block, buffer, 0, end_read_block);
// Write to MMF
writer.WriteArray<byte>(length - end_read_block, buffer, 0, end_read_block);
}
}
}我尝试复制一个文件并将其粘贴到它正在工作的另一个位置
但当我尝试使用Parallel.foreach或Parallel.for复制一个文件时,所复制的文件与源文件不同
(我评论了Parallel.foreach部分)
我不明白为什么
谢谢
发布于 2012-08-16 00:33:31
在你的代码中;
Parallel.ForEach<int>(offset_array, offset =>
{
// Read from MMF
buffer = new byte[read_block];
reader.ReadArray<byte>(offset, buffer, 0, read_block);
// Write to MMF
writer.WriteArray<byte>(offset, buffer, 0, read_block);
});buffer是一个共享变量,所以所有线程都会共享它。例如,线程1将分配缓冲区,从文件中读取,线程2将重新分配缓冲区并读取文件,线程1将写入线程2的缓冲区的内容。
为了让它更好地工作,让buffer成为循环中的一个局部变量,a‘’la;
Parallel.ForEach<int>(offset_array, offset =>
{
// Read from MMF
byte[] buffer = new byte[read_block];
reader.ReadArray<byte>(offset, buffer, 0, read_block);
// Write to MMF
writer.WriteArray<byte>(offset, buffer, 0, read_block);
});这将允许所有线程拥有自己的本地缓冲区。
尽管看看documentation会让事情看起来很糟糕,但任何实例方法(读数组/写数组)都不能保证是线程安全的。换句话说,即使您修复了缓冲区问题,也不能保证一切都会正常工作。
发布于 2012-08-16 00:42:32
您复制文件的方法不是很好。除了约阿希姆·伊萨克森描述的问题之外,还有一个问题是你同时从多个线程访问文件流。这意味着可能发生这样的情况:一个线程T1读取数据,然后调度器将控制传递给线程T2,后者读取数据,然后将其写入目标。当控制权返回给T1并且它写入读取数据时,您将得到一个损坏的文件。没有理由使用并发复制文件,因为CPU不是此操作瓶颈。你不会得到更快的结果,你只会浪费CPU周期。
https://stackoverflow.com/questions/11973132
复制相似问题