2011-01-07 13 views
2

Ich arbeite daran, einige Dateien in ein anderes Verzeichnis in meinem Projekt zu verschieben, und es funktioniert großartig, außer dass ich nicht verifizieren kann, dass es richtig verschoben wurde.Verify-Datei wird in Java kopiert

Ich möchte überprüfen, die Länge der Kopie ist das gleiche wie das Original und dann möchte ich das Original löschen. Ich schließe beide FileStreams, bevor ich meine Überprüfung durchführe, aber es schlägt immer noch fehl, weil die Größen unterschiedlich sind. Unten ist mein Code zum Schließen der Streams, Verifizierung und Löschung. Ich brauche nur eine bessere Überprüfungsmethode

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

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

Der Rest des Codes, bevor diese eine Util wird unter Verwendung der Ströme zu kopieren, und es ist alles in Ordnung so wirklich funktioniert.

+0

Warum sollten Sie erwarten, dass eine Schreiboperation, die keine Ausnahme ausgelöst hat, irgendwie eine unidentische Datei zu ihrer Quelle erzeugt hat? –

+0

Weil verrückte Dinge passiert sind, und während Datenverlust nicht das Ende der Welt wäre, würde ich lieber nicht auf meiner Uhr passieren. – Shaded

+0

Wie liest/schreibt man die Datei? und ist das eine Binär- oder Textdatei? –

Antwort

2

Sie könnten eine Prüfsumme in Ihre Kopieroperation einfügen. Führen Sie eine Prüfsumme für die Zieldatei aus und stellen Sie fest, dass sie mit einer Prüfsumme für die Quelle übereinstimmt.

+0

Ich denke, du bist der erste Kommentar war direkt mit mir paranoid, ich war auf der Suche nach dem falschen Problem und du warst der erste, um mich darauf anzurufen, damit Sie die Antwort bekommen. Möglicherweise muss ich einen neuen Thread öffnen, um herauszufinden, warum meine Löschung nicht funktioniert. – Shaded

4

Eine wunderbare Möglichkeit, die Sie überprüfen können, ist, MD5-Hashes zu vergleichen. Die Überprüfung der Dateilänge bedeutet nicht, dass sie identisch sind. Während MD5-Hashes nicht bedeutet, dass sie auch gleich sind, ist es besser als die Überprüfung der Länge, obwohl ein längerer Prozess.

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 = neuer BigInteger (1, md5sum); String output = bigInt.toString (16); 'ist eine interessante Möglichkeit, Hex-Strings für Digest zu generieren. –

+0

+1 für geben Sie mir eine genauere Methode mit einem Beispiel. Vielen Dank! – Shaded

2

könnten Sie verwenden commons io:

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

oder Sie könnten Prüfsumme Methoden verwenden:

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

Leider habe ich diese Lib nicht auf meinem Projekt verfügbar, so dass es nicht funktioniert. – Shaded

3

Wenn Sie keine Ausnahme erhalten, während Ströme kopieren, sollten Sie in Ordnung sein. Stellen Sie sicher, dass Ausnahmen, die durch die Methode close ausgelöst werden, nicht ignoriert werden!

Update: Wenn Sie FileOutputStream verwenden, können Sie auch sicherstellen, dass alles wurde richtig geschrieben fileOutputStream.getFD().sync() durch den Aufruf vor Ihrer fileOutputStream schließen.

Natürlich, wenn Sie absolut sicherstellen wollen, dass Dateien die gleichen sind, können Sie ihre Prüfsummen/Digests vergleichen, aber das klingt etwas paranoid zu mir.

+0

Es ist in der Tat nützlich zu wissen, wie man die Checksum verwendet, aber ich bin immer noch dabei. Ohne eine Ausnahme denke ich, dass es unwahrscheinlich ist, dass ein Kopiervorgang schlechte Ergebnisse bringt. Selbst über ein Netzwerk würde ich erwarten, dass die Schnittstellen zu diesen Protokollen solche Dinge für den Entwickler erledigen. –

+0

@Yock: Ja, ich habe tatsächlich gesehen FileOutputStream.close() -Methode werfen IOException beim Schreiben von Datei über NFS. –

1

Wenn die Größen unterschiedlich sind, wird der Ausgabestrom möglicherweise nicht vor dem Schließen gespült.

Welche Datei ist größer? Wie groß sind die einzelnen Dateien? Haben Sie sich die beiden Dateien angesehen, um zu sehen, was anders ist?

Verwandte Themen