2010-11-26 31 views

Respuesta

4

utilice hashlib para obtener el md5 de cada archivo y compare los resultados.

#! /bin/env python 
import hashlib 
def filemd5(filename, block_size=2**20): 
    f = open(filename) 
    md5 = hashlib.md5() 
    while True: 
     data = f.read(block_size) 
     if not data: 
      break 
     md5.update(data) 
    f.close() 
    return md5.digest() 

if __name__ == "__main__": 
    a = filemd5('/home/neo/todo') 
    b = filemd5('/home/neo/todo2') 
    print(a == b) 

Actualización: A partir de Python 2.1 hay un filecmp module que hace exactamente lo que quiere, y tiene métodos para comparar directorios también. nunca supe acerca de este módulo, todavía estoy aprendiendo Python mismo :-)

>>> import filecmp 
>>> filecmp.cmp('undoc.rst', 'undoc.rst') 
True 
>>> filecmp.cmp('undoc.rst', 'index.rst') 
False 
+0

¿Cuál es el propósito de realizar un hash MD5? ¿Por qué no simplemente leer los dos archivos bloque por bloque hasta que un bloque sea diferente? Esto omitiría la fase de cálculo de MD5, * y * sería robusto frente a las colisiones hash (ciertamente improbables). – EOL

+2

@EOL tiene un punto válido allí, eso también funcionará. La única ventaja que veo es almacenar la fecha modificada del archivo hash + y volver a usar esos valores precalculados en el futuro. – invert

4

Ok, esto podría necesitar dos respuestas por separado.

Si tiene que comparar muchos archivos, vaya a la suma de comprobación y guarde en caché la suma de comprobación para cada archivo. Para estar seguro, compara el byte de archivos coincidentes para byte después.

Si solo tiene dos archivos, vaya directamente para la comparación de bytes porque debe leer el archivo de todos modos para calcular la suma de comprobación.

En ambos casos, utilice el tamaño del archivo como una forma temprana de comprobar la desigualdad.

+0

Incluso cuando se comparan varios archivos, la suma de comprobación podría ser contraproducente. Si solo quieres comprobar que 'a == b == c == d', entonces no veo el sentido. Si quiere algo como 'e in (a, b, c, d)', y luego quiere hacerlo con 'e, f, g', etc., entonces creo que la suma de comprobación comienza a pagar por sí misma. – aaronasterling

+1

Bueno, el caso más común para comparar múltiples archivos es encontrar duplicados. Al menos, rara vez he visto la necesidad de asegurarme de que varios archivos son todos iguales. – Joey

-2

Me gustaría hacer la suma de comprobación con MD5 (por ejemplo) en lugar de byte comaprasion más la verificación de la fecha y depende de usted necesita verificación de nombre.

+2

¿Qué tiene que ver la fecha de un archivo con su contenido? – Joey

+0

Checksum es una buena solución, estoy de acuerdo, pero ¿qué quiere decir decir "fechas de verificación"? –

+2

¿No tiene que leer ambos archivos para obtener su suma de verificación de todos modos? Si es así, entonces creo que toda la suma de comprobación es agregar un riesgo de colisión. Editar: a menos que quiera comparar varios archivos como Joey acaba de decir en una respuesta. – aaronasterling

-2

¿Qué tal desgranar a cmp?

import commands 
status, output = commands.getstatusoutput("/usr/bin/cmp file1 file2") 
if (status == 0): 
    print "files are same" 
elif (status == 1): 
    print "files differ" 
else: 
    print "uh oh!" 
+1

Buena suerte en un sistema Windows ;-) – Joey

+0

Instalar cygwin. –

+1

No es una solución multiplataforma ... –

0

Antes de intentar cualquiera de las otras soluciones, es posible que desee hacer os.path.getsize(...) en ambos archivos. Si eso difiere, no hay necesidad de comparar bytes o calcular suma de comprobación.

Por supuesto, esto solo ayuda si el tamaño del archivo no es fijo.

Ejemplo:

def foo(f1, f2): 
    if not os.path.getsize(f1) == os.path.getsize(f2): 
     return False # Or similar 

    ... # Checksumming/byte-comparing/whatever 
9

¿Qué hay de filecmp módulo? Puede hacer la comparación de archivos de muchas maneras diferentes con diferentes compensaciones.

Y aún mejor, que es parte de la biblioteca estándar:

http://docs.python.org/library/filecmp.html

+0

Módulo interesante, pero le da menos de lo que se pregunta en la pregunta: "devuelve verdadero si [los archivos] * parecen * iguales, de lo contrario es falso". Considero que esto significa que la comparación es aproximada. Sería interesante saber cuán aproximado es. Además, no pude encontrar cómo se puede hacer la comparación "de muchas maneras diferentes con diferentes intercambios": ¿podría profundizar en esto? – EOL

+0

El uso de hashlib para obtener el MD5 también es 'aproximado'. La única forma de estar seguro es haciendo una comparación byte a byte. filecmp lo soporta, al pasar False a través del parámetro 'shallow'. – wump

Cuestiones relacionadas