2013-01-04 52 views
8

私はWPFアプリケーションをC#で作成していますが、いくつかのファイルを移動する必要があります。つまり、ファイルが作成されたかどうかを知る必要があります。これを行うには、私は、ファイルが移動した後、ターゲットディレクトリになることを確認するチェックを書いた - 問題は、ファイルが移動し終わる前に、時々私がチェックに行くことです:System.IO.File.Move - 移動完了を待つ方法は?

System.IO.File.Move(file.FullName, endLocationWithFile); 

      System.IO.FileInfo[] filesInDirectory = endLocation.GetFiles(); 
      foreach (System.IO.FileInfo temp in filesInDirectory) 
      { 
       if (temp.Name == shortFileName) 
       { 

        return true; 
       } 
      } 

      // The file we sent over has not gotten to the correct directory....something went wrong! 
      throw new IOException("File did not reach destination"); 

     } 
     catch (Exception e) 
     { 
      //Something went wrong, return a fail; 
      logger.writeErrorLog(e); 
      return false; 
     } 

誰かが言うことができます?私はどのようにファイルが実際に目的地に到達することを確認します - 私は非常に大きくなる可能性が移動されるファイル - (2時間までのフルHD MP4ファイル)

ありがとう!

+2

どのようにストリームをコピーするのではなく、 'Move'を使用することによって、自分自身を移動管理について?あなたは何が続いているのかを正確に知るでしょう。 – spender

+0

素晴らしい音....それを行う方法に関する少し詳しい情報をリンクに投稿できますか? – Mizmor

+0

私はあなたを助けるための答えを追加しました。 – spender

答えて

7

あなたがファイルを確実にするためにAysncAwaitでストリームを使用することができますが、完全にこのような

何かが動作するはずコピーされます。

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    string sourceFile = @"\\HOMESERVER\Development Backup\Software\Microsoft\en_expression_studio_4_premium_x86_dvd_537029.iso"; 
    string destinationFile = "G:\\en_expression_studio_4_premium_x86_dvd_537029.iso"; 

    MoveFile(sourceFile, destinationFile); 
} 

private async void MoveFile(string sourceFile, string destinationFile) 
{ 
    try 
    { 
     using (FileStream sourceStream = File.Open(sourceFile, FileMode.Open)) 
     { 
      using (FileStream destinationStream = File.Create(destinationFile)) 
      { 
       await sourceStream.CopyToAsync(destinationStream); 
       if (MessageBox.Show("I made it in one piece :), would you like to delete me from the original file?", "Done", MessageBoxButton.YesNo) == MessageBoxResult.Yes) 
       { 
        sourceStream.Close(); 
        File.Delete(sourceFile); 
       } 
      } 
     } 
    } 
    catch (IOException ioex) 
    { 
     MessageBox.Show("An IOException occured during move, " + ioex.Message); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("An Exception occured during move, " + ex.Message); 
    } 
} 

あなたはVS2010を使用した場合には、使用するAsync CTPをインストールする必要があります新しいAsync/Await構文

+0

これは本当にきれいな解決策です - ありがとう! – Mizmor

+0

なぜあなたの '使用中 'の中に' if'があるのですか?つまり、なぜ '(MessageBox.Show(...))File.Delete(sourceFile);'が 'using'ブロックの外側にあるのでしょうか? (より良いのは、 'bool deleteSource = true'引数を含むことです。) –

+0

両方とも同じように動作します。'使用する 'の内部の 'if'は違いがないので、' using'文はdisposeがストリーム上で確実に呼び出され、 'if'ステートメントとの関連性が全くない場合、コードを100通り書くことができ、同じ効果を得ることができます。 –

1

あなたは、元のディレクトリから消えたファイルを監視し、それらが実際にターゲットディレクトリに登場したことを確認できました。

私はファイルウォッチャーで素晴らしい経験はありませんでした。私はおそらく、別のスレッドやタイマーが定期的に元の場所から消えるようにファイルをチェックし、それらが新しい場所にあることを確認し、おそらく(あなたの環境や環境に応じて)AutoResetEventの移動待ちのスレッドを持っています。ニーズ)は、ファイルの一貫性チェック(MD5チェックなど)を実行します。これらの条件が満たされると、「チェッカー」スレッド/タイマーがAutoResetEventをトリガーし、元のスレッドが進行できるようにします。

「これは長すぎます」ロジックを「チェッカー」に含めます。

0

あなたは、アプリケーションの実行を何時間も停止しないように、別のスレッドで動きが発生したほうがよいでしょう。

プログラムが完了して移動せずに続けることができない場合は、ダイアログを開くことができ、進捗トラッカーを更新するために定期的に移動スレッド上で確認してください。これにより、ユーザーにフィードバックが提供され、あたかもプログラムが凍っているかのような感情を感じさせなくなります。

この上の情報と例がここにあります: http://hintdesk.com/c-wpf-copy-files-with-progress-bar-by-copyfileex-api/

1

ストリームをコピーしてコピーを自分で管理しないのはなぜ?

//http://www.dotnetthoughts.net/writing_file_with_non_cache_mode_in_c/ 
const FileOptions FILE_FLAG_NO_BUFFERING = (FileOptions) 0x20000000; 

//experiment with different buffer sizes for optimal speed 
var bufLength = 4096; 

using(var outFile = 
    new FileStream(
     destPath, 
     FileMode.Create, 
     FileAccess.Write, 
     FileShare.None, 
     bufLength, 
     FileOptions.WriteThrough | FILE_FLAG_NO_BUFFERING)) 
using(var inFile = File.OpenRead(srcPath)) 
{ 
    //either 
    //inFile.CopyTo(outFile); 

    //or 
    var fileSizeInBytes = inFile.Length; 
    var buf = new byte[bufLength]; 
    long totalCopied = 0L; 
    int amtRead; 
    while((amtRead = inFile.Read(buf,0,bufLength)) > 0) 
    { 
     outFile.Write(buf,0,amtRead); 
     totalCopied += amtRead; 
     double progressPct = 
      Convert.ToDouble(totalCopied) * 100d/fileSizeInBytes; 
     progressPct.Dump(); 
    } 
} 
//file is written 
0

定期的にバックグラウンドタスクでcopiエドファイル サイズは

0

は最近、同様の問題を得た(あなたはファイル間の比較のハッシュを追加することができます)、元のファイルのファイルサイズに達しました。

が待っていない は、イベントに反応する

OnBackupStarts(); 
//.. do stuff 

new TaskFactory().StartNew(() => 
       { 
        OnBackupStarts() 
        //.. do stuff 
        OnBackupEnds(); 
       }); 


void OnBackupEnds() 
    { 
     if (BackupChanged != null) 
     { 
      BackupChanged(this, new BackupChangedEventArgs(BackupState.Done)); 
     } 
    } 

関連する問題