Je dois synchroniser de gros fichiers sur certaines machines. Les fichiers peuvent atteindre jusqu'à 6 Go. La synchronisation sera effectuée manuellement toutes les quelques semaines. Je ne peux pas prendre le nom de fichier en considération car ils peuvent changer à tout moment.
Mon plan est de créer des sommes de contrôle sur le PC de destination et sur le PC source, puis de copier tous les fichiers avec une somme de contrôle, qui ne sont pas déjà dans la destination, vers la destination. Ma première tentative était quelque chose comme ceci:
using System.IO;
using System.Security.Cryptography;
private static string GetChecksum(string file)
{
using (FileStream stream = File.OpenRead(file))
{
SHA256Managed sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
return BitConverter.ToString(checksum).Replace("-", String.Empty);
}
}
Le problème était l'exécution:
- avec SHA256 avec un fichier de 1,6 Go -> 20 minutes
- avec MD5 avec un fichier de 1,6 Go -> 6,15 minutes
Existe-t-il un meilleur moyen - plus rapide - d'obtenir la somme de contrôle (peut-être avec une meilleure fonction de hachage)?
la source
Réponses:
Le problème ici est que
SHA256Managed
lit 4096 octets à la fois (hériter deFileStream
et remplacerRead(byte[], int, int)
pour voir combien il lit dans le flux de fichiers), ce qui est un tampon trop petit pour les E / S de disque.Pour accélérer les choses (2 minutes pour hachant fichier 2 Gb sur ma machine avec SHA256, 1 minute pour MD5) wrap
FileStream
dansBufferedStream
et définir la taille de la mémoire tampon de taille raisonnable (j'ai essayé avec un tampon ~ 1 Mb):la source
Ne faites pas la somme de contrôle du fichier entier, créez des sommes de contrôle tous les 100 Mo environ, de sorte que chaque fichier possède une collection de sommes de contrôle.
Ensuite, lorsque vous comparez les sommes de contrôle, vous pouvez arrêter de comparer après la première somme de contrôle différente, sortir tôt et vous éviter de traiter l'ensemble du fichier.
Cela prendra encore tout le temps pour des fichiers identiques.
la source
Comme l'a noté Anton Gogolev , FileStream lit 4096 octets à la fois par défaut, mais vous pouvez spécifier toute autre valeur à l'aide du constructeur FileStream:
Notez que Brad Abrams de Microsoft a écrit en 2004:
la source
la source
Appelez le port Windows de md5sum.exe . C'est environ deux fois plus rapide que l'implémentation .NET (au moins sur ma machine en utilisant un fichier de 1,2 Go)
la source
Ok - merci à vous tous - laissez-moi conclure ceci:
la source
J'ai fait des tests avec la taille du tampon, en exécutant ce code
Et j'ai testé avec un fichier de 29½ Go, les résultats étaient
J'utilise un processeur i5 2500K, 12 Go de RAM et un disque SSD OCZ Vertex 4 256 Go.
Alors j'ai pensé, qu'en est-il d'un disque dur standard de 2 To. Et les résultats étaient comme ça
Je recommanderais donc soit pas de tampon, soit un tampon de max 1 mill.
la source
Vous faites quelque chose de mal (probablement trop petit tampon de lecture). Sur une machine d'un âge indécent (Athlon 2x1800MP de 2002) qui a DMA sur le disque probablement hors de contrôle (6,6M / s est sacrément lent lors de lectures séquentielles):
Créez un fichier 1G avec des données "aléatoires":
1m5.299s
1m58.832s
C'est aussi bizarre, md5 est toujours plus lent que sha1 pour moi (relance plusieurs fois).
la source
Je sais que je suis en retard pour faire la fête mais que j'ai effectué des tests avant de mettre en œuvre la solution.
J'ai effectué des tests contre la classe MD5 intégrée et aussi md5sum.exe . Dans mon cas, la classe intégrée a pris 13 secondes où md5sum.exe environ 16-18 secondes à chaque exécution.
la source
Vous pouvez jeter un œil à XxHash.Net ( https://github.com/wilhelmliao/xxHash.NET )
L'algorithme xxHash semble être plus rapide que tous les autres.
Quelques benchmarks sur le site xxHash: https://github.com/Cyan4973/xxHash
PS: je ne l'ai pas encore utilisé.
la source