2012-10-22 25 views
12

私はバックアップソリューション(種類の)を書いています。単にコピー位置Cからファイル:位置Zへ\とペーストを:ファイルが変更された場合の解決方法?

\速度を確保するためには、コピーし、元のファイルが存在するかどうかをチェック貼り付ける前に、高速です。そうであれば、コピーを続行するか、バックアップファイルが最新のものかどうかを調べるために、いくつかの「計算」を実行します。これらの計算は難しいと思っています。

元々、私はファイルサイズを比較しましたが、これはファイルとそれを同じサイズに変更することは非常に可能であるため十分ではありません(例えば、メモ帳で文字Cを保存することは、文字Tを保存しました)。

したがって、変更日が異なるかどうかを調べる必要があります。現時点では、FileInfoクラスを使用してファイル情報を取得していますが、すべてのフィールドを確認した後、適切なものは何もありません。

どのように私は私が変更されたファイルをコピーしてることを確認するためにチェックすることができますか?あなたが好きなことがあり、私は比較していますファイルの一部が10ギガバイト

+2

ほとんどのファイルシステムには、「最後に変更された時間」と呼ばれる優れたメタ属性があります。 –

+0

しかし、私はFileInfoからそれを取得しません - それはおそらく完璧だと私は同意するが、どのクラスが私にその情報を提供するか分からない。 – Dave

+1

FileInfo.LastWriteTimeにはこの情報がありませんか?それは私がこの質問から得た印象です:http://stackoverflow.com/questions/1185378/how-to-get-modified-date-from-file-in-c-sharp – JoshVarty

答えて

13

変更日付で行くことは信頼性が低くなります - コンピュータの時計は、それが同期する際、後方に行く、または手動で調整したときにすることができます。修正された日付を管理するという観点からは、ファイルを変更またはコピーするときに、正しく動作しないプログラムもあります。

制御された環境で働くかもしれない、アーカイブビットで行くが、別のソフトウェアが稼働しているが、同様のアーカイブビットを使用している場合はどうなりますか?

The Windows archive bit is evil and must be stopped

あなたが(ほぼ)完全な信頼性が必要な場合は、何をやるべきことは、最後のハッシュ値をSHA1のような良いハッシュ関数を使用して、バージョンをバックアップして、ハッシュ値の変更は、あなたがアップロードした場合に保存されます新しいコピーここで

は、底面のコードサンプルと一緒にSHA1クラスです:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx

はちょうどそれを介してファイルのバイトを実行し、ハッシュ値を格納します。ファイルをメモリにロードする代わりに、バイト配列を使用して、特に大容量ファイルの場合はメモリ使用量を減らす代わりに、FileStreamを渡してください。

あなたは速度と信頼性のために必要に応じてプログラムを調整するために、様々な方法で変更された日付でこれを組み合わせることができます。たとえば、ほとんどのバックアップの変更日を確認したり、システムがアイドル状態の間に実行されるハッシュチェッカーを定期的に実行して、何も見逃していないことを確認することができます。場合によっては、変更された日付は変更されますが、ファイルの内容は同じです(つまり、同じデータで上書きされます)。その場合、ハッシュを再計算してもファイル全体が再送信されることはありません。

ほとんどのバージョンコントロールシステムでは、ハッシュと変更された日付で何らかの組み合わせのアプローチが使用されます。

あなたのアプローチは、完全バックアップをしたくない場合や、毎回すべてのデータを送信したくない場合は、通常、パフォーマンス管理と信頼性の妥協を伴うリスク管理を行います。このため、しばらくの間、「フルバックアップ」を行うことが重要です。

+0

明確にするために、外部ファイルまたはデータベース(または同様のもの)の意味ですか? – Dave

+3

これはあなたのシステムの実装方法に依存します:)値のデータベースを保持することができます。あるいは、使用したサブバージョンを実行し、バックアップされたすべてのファイルのハッシュを含むバックアップされた場所の中に隠しディレクトリを作成できますアップ。 Subversionはそれから離れ、バージョン管理されたディレクトリ構造のルートにある隠しディレクトリにデータベースを保持します。 –

+0

私は見ていますが、これはこのデータを他の場所に保存することに依存します。時間をかけて助けてくれてありがとう。 – Dave

7

までになり、これが問題である可能性があり、私はMD5チェックサムを使用するように提案を見てきましたが、私は心配

EDIT FileSystemWatcherクラスをチェックしてください。

"このクラスを使用すると、ディレクトリの変更を監視し、何かが変更されたときに イベントを発生させることができます。

あなたのコードは、イベントを処理し、ファイルを処理することができます。

コードソース - MSDN:

// Create a new FileSystemWatcher and set its properties. 
FileSystemWatcher watcher = new FileSystemWatcher(); 
watcher.Path = args[1]; 

/* Watch for changes in LastAccess and LastWrite times, and 
    the renaming of files or directories. */ 
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
    | NotifyFilters.FileName | NotifyFilters.DirectoryName; 

// Only watch text files. 
watcher.Filter = "*.txt"; 

// Add event handlers. 
watcher.Changed += new FileSystemEventHandler(OnChanged); 
watcher.Created += new FileSystemEventHandler(OnChanged); 
watcher.Deleted += new FileSystemEventHandler(OnChanged); 
watcher.Renamed += new RenamedEventHandler(OnRenamed); 
+1

私のプログラムは24/7のフォルダを見るようには設計されておらず、コピー/ペースト時にオンザフライで2つのファイルのみをチェックします。 +1これは良い情報であり、代わりに便利ですが、私は2つのファイルを比較しようとしています – Dave

+1

FYI、これはMono互換の解決策ではないようです – joelc

10

あなたは彼らのハッシュによってファイルを比較することができます。コンテンツが変更された場合

private byte[] GetFileHash(string fileName) 
{ 
    HashAlgorithm sha1 = HashAlgorithm.Create(); 
    using(FileStream stream = new FileStream(fileName,FileMode.Open,FileAccess.Read)) 
     return sha1.ComputeHash(stream); 
} 

、ハッシュは異なるものになります。

+0

+1このコードをありがとうございます。これは最後の2バイトを比較するのがとても簡単で素敵です。良い答え、ありがとう – Dave

+1

最後の2バイトだけを比較するには不十分です。すべてのバイトを比較するには 'hash1.SequenceEqual(hash2)'を使用してください –

+0

2バイトがソースと宛先です – Dave

1

一般に、OSにファイルが変更されたかどうかを追跡するようにします。

あなたが使用している場合:

File.GetAttributes 

とアーカイブフラグをチェックし、それが最後にアーカイブされたため、ファイルが変更された場合、これはあなたを教えてくれます。私はXCOPYと同様のコピーが完了したらこのフラグをリセットすると信じていますが、これを自分で処理する必要があるかもしれません。

あなたは簡単に使用してDOSでフラグをテストすることができます。

dir /aa yourfilename 

それとも、Windowsエクスプローラで属性の列を追加します。

1

通常、ファイルアーカイブフラグは、ファイルをバックアップする必要があるかどうかを確認するために、バックアッププログラムによって使用されます。 Windowsがファイルを変更または作成すると、アーカイブフラグが設定されます(here参照)。ファイルをバックアップした後

if ((File.GetAttributes(fileName) & FileAttributes.Archive) == FileAttributes.Archive) 
{ 
    // Archive file. 
} 

、アーカイブフラグをクリア:アーカイブフラグはファイルがバックアップする必要があるかどうかを決定するために設定されているかどうかをチェックし

File.SetAttributes(fileName, File.GetAttributes(fileName) & ~FileAttributes.Archive); 

これは、他のプログラム(例えば、システムを負うものではありませんバックアップソフトウェア)がアーカイブフラグをクリアしています。

+0

これは素晴らしいです。ありがとう、非常によく説明されています。 – Dave

関連する問題