5

次のシナリオがあります。複数(約10,50,200、...)のファイルをコピーする必要があります。私はそれを次々と同期して行います。これはそのための私のコードスニペットです。

static void Main(string[] args)
        {
            string path = @"";
            FileSystemWatcher listener = new FileSystemWatcher(path);
            listener.Created += new FileSystemEventHandler(listener_Created);
            listener.EnableRaisingEvents = true;

            while (Console.ReadLine() != "exit") ;
        }

        public static void listener_Created(object sender, FileSystemEventArgs e)
        {
            while (!IsFileReady(e.FullPath)) ;
            File.Copy(e.FullPath, @"D:\levani\FolderListenerTest\CopiedFilesFolder\" + e.Name);
        }

そのため、あるフォルダにファイルが作成されて使用できるようになったら、そのファイルを次々にコピーしますが、ファイルが使用できるようになったらすぐにコピーを開始する必要があります。だから私はスレッドを使うべきだと思います。だから..並列コピーを実装する方法は?

@クリス

ファイルの準備ができているかどうかを確認します

public static bool IsFileReady(String sFilename)
        {
            // If the file can be opened for exclusive access it means that the file
            // is no longer locked by another process.
            try
            {
                using (FileStream inputStream = File.Open(sFilename, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    if (inputStream.Length > 0)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }

                }
            }
            catch (Exception)
            {
                return false;
            }
        }
4

3 に答える 3

12

メカニカルディスクから並列I/Oを実行することは悪い考えであり、速度が低下するだけです。メカニカルヘッドは、次の読み取り位置を探すために毎回回転する必要があり(非常に遅いプロセス)、スレッドごとにバウンスするためです。実行する順番を取得します。

シーケンシャルアプローチに固執し、単一のスレッドでファイルを読み取ります。

于 2012-06-14T08:09:06.550 に答える
2

今はそれだけです(@Tudorが言っていることです)が、ファイルを並行してコピーすると、断片化のためにハードドライブから混乱が生じます。私のアプリでは、以前に生成された200個のファイルのキューに入れられたコピーを使用して、それらを「線形」方式でハードドライブに配置します。

あなたはここで主題についてもう少し読むことができます。

于 2012-06-14T08:19:36.310 に答える
2

あなたはおそらくThreadすべての処理を行うものを持っている可能性があります

Queue files = new Queue();

static void Main(string[] args)
{
      string path = @"";
      FileSystemWatcher listener = new FileSystemWatcher(path);
      Thread t = new Thread(new ThreadStart(ProcessFiles));
      t.Start();
      listener.Created += new FileSystemEventHandler(listener_Created);
      listener.EnableRaisingEvents = true;

      while (Console.ReadLine() != "exit") ;
}


public static void listener_Created(object sender, FileSystemEventArgs e)
{
    files.Enqueue(e.FullPath);
}

void ProcessFiles()
{
    while(true)
    {
        if(files.Count > 0)
        {
              String file = files.Dequeue();
              while (!IsFileReady(file)) ;

              File.Copy(file, @"D:\levani\FolderListenerTest\CopiedFilesFolder\" +           file);
        }
    }
}

そして、あなたのlistenerイベントでは、ファイル名をキューに追加します。

次にThread、キューからファイル名を取得し、そこから処理を実行できます。

于 2012-06-14T08:59:41.143 に答える