2011-01-07 5 views
2

私はプロジェクト内の別のディレクトリにいくつかのファイルを移動しようとしていますが、正しく動作しているかどうかを確認できないという点を除いて、ファイルがJavaでコピーされていることを確認してください

コピーの長さが元のものと同じであることを確認してから、元のファイルを削除したいと考えています。私は私の検証を行う前に両方のFileStreamsを閉じていますが、サイズが違うのでまだ失敗します。以下は、ストリームを閉じ、検証と削除を行うための私のコードです。

in.close(); 
out.close(); 

if (encCopyFile.exists() && encCopyFile.length() == encryptedFile.length()) 
    encryptedFile.delete(); 

この前のコードの残りの部分は、ストリームをコピーするために使用率を使用している、そしてそれはすべて正常に動作していますので、実際に、私はちょうど良く検証方法を必要としています。

+0

なぜ例外をスローしなかった書き込み操作が、どういうわけかそのソースに一意のファイルを生成しないと思いますか? –

+0

奇妙なことが起こったので、データの消失は世界の終わりにはならないだろうが、私はむしろ私の時計には起こりません。 – Shaded

+0

どのようにファイルを読み書きしていますか?これはバイナリファイルかテキストファイルですか? –

答えて

2

コピー操作にチェックサムを含めることができます。宛先ファイルに対してチェックサムを実行し、ソース上のチェックサムと一致することを確認します。

+0

私はあなたが最初のコメントをしていると思いますが、私は間違った問題を見ていました。あなたは私にそれを呼び出す最初の人だったので、あなたは答えを得ます。なぜ私の削除が動作していないのか理解するために新しいスレッドを開かなければならないかもしれません。 – Shaded

4

確認できる素晴らしい方法は、md5ハッシュを比較することです。ファイルの長さをチェックしても、同じであるとは限りません。 md5ハッシュは同じであるということを意味するわけではありませんが、長いプロセスではあるが長さをチェックするよりも優れています。

public class Main { 

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException { 
     System.out.println("Are identical: " + isIdentical("c:\\myfile.txt", "c:\\myfile2.txt")); 
    } 

    public static boolean isIdentical(String leftFile, String rightFile) throws IOException, NoSuchAlgorithmException { 
     return md5(leftFile).equals(md5(rightFile)); 
    } 

    private static String md5(String file) throws IOException, NoSuchAlgorithmException { 
     MessageDigest digest = MessageDigest.getInstance("MD5"); 
     File f = new File(file); 
     InputStream is = new FileInputStream(f); 
     byte[] buffer = new byte[8192]; 
     int read = 0; 
     try { 
      while ((read = is.read(buffer)) > 0) { 
       digest.update(buffer, 0, read); 
      } 
      byte[] md5sum = digest.digest(); 
      BigInteger bigInt = new BigInteger(1, md5sum); 
      String output = bigInt.toString(16); 
      return output; 
     } finally { 
      is.close(); 
     } 
    } 
} 
+0

'BigInteger bigInt =新しいBigInteger(1、md5sum); String output = bigInt.toString(16); 'は、ダイジェスト用の16進文字列を生成する興味深い方法です。 –

+0

+1を使ってもっと正確な方法を教えてください。ありがとう! – Shaded

2

あなたは、IOコモンズを使用することができます。

org.apache.commons.io.FileUtils.contentEquals(File file1, File file2) 

か、チェックサムメソッドを使用することができます。

org.apache.commons.io.FileUtils: 
static Checksum checksum(File file, Checksum checksum) //Computes the checksum of a file using the specified checksum object. 
static long checksumCRC32(File file) //Computes the checksum of a file using the CRC32 checksum routine. 
+1

残念ながら私のプロジェクトで利用可能なlibを持っていないので動作しません。 – Shaded

3

ストリームをコピーしているときに例外を取得していない場合は、[OK]をする必要があります。 closeメソッドでスローされた例外を無視しないようにしてください!

更新:あなたがFileOutputStreamを使用する場合は、すべてがあなたのfileOutputStreamを閉じる前にfileOutputStream.getFD().sync()を呼び出すことによって、適切に書かれたことを確認することができます。

もちろん、ファイルが同じであることを絶対に確認したい場合は、チェックサム/ダイジェストを比較することができますが、それは私には不快感を与えます。

+0

チェックサムの使い方を理解することは本当に便利ですが、私はまだこれに固執しています。例外なく、私はコピー操作が悪い結果をもたらす可能性は非常に低いと思います。ネットワーク上でさえ、私はこれらのプロトコルへのインターフェイスが開発者にとってこの種のものを扱うことを期待しています。 –

+0

@yock:NFS経由でファイルを書き込むときにIOExceptionをスローするFileOutputStream.close()メソッドが実際に見えました。 –

1

サイズが異なる場合は、出力ストリームを閉じる前に出力ストリームをフラッシュしていない可能性があります。

どのファイルが大きいですか?各ファイルのサイズは?実際には2つのファイルを見て、何が違うのか見てきましたか?

関連する問題