pourquoi fsutil.exe prend moins de temps pour écrire un fichier volumineux sur le disque que par programme?

cette question est en fonction de ce sujet: créer un fichier factice énorme en quelques secondes en c #

Je viens de vérifier le fichier fsutil.exe dans XP / Vista / Seven pour écrire une énorme quantité de données factices dans le disque de stockage et cela prend moins de temps pour écrire un fichier aussi volumineux que de manière programmatique.

Lorsque j’essaie de faire la même chose avec l’aide de .net, cela prendra beaucoup plus de temps que fsutil.exe.

note: je sais que .net n’utilise pas de code natif à cause de cela j’ai juste vérifié ce problème avec l’API natif aussi comme suit:

long int size = DiskFree('L' - 64); const char* full = "fulldisk.dsk"; __try{ Application->ProcessMessages(); HANDLE hf = CreateFile(full, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0); SetFilePointer(hf, size, 0, FILE_BEGIN); SetEndOfFile(hf); CloseHandle(hf); }__finally{ ShowMessage("Finished"); exit(0); 

et la réponse était aussi égale que les résultats .net.

mais avec l’aide de fsutil.exe, cela prend moins de temps que ci-dessus ou les approches .net disent que c’est 2 fois plus rapide

Exemple: pour écrire 400 Mo avec .net, il faudra environ 40 secondes pour que fsutil.exe prenne environ 20 secondes ou moins.

Y a-t-il une explication à ce sujet? ou quelle fonction fsutil.exe utilise qui a cette rapidité à écrire?

Je ne sais pas exactement ce que fait fsutil, mais je connais deux façons d’écrire un fichier volumineux qui est plus rapide que ce que vous avez fait ci-dessus (ou en cherchant à la longueur voulue et en écrivant un zéro, ce qui a le même résultat).

Le problème avec ces approches est qu’elles remplissent le fichier au moment où vous écrivez.

Vous pouvez éviter le remplissage à zéro de l’une des manières suivantes:

  1. Créer un fichier fragmenté. La taille est marquée à l’endroit souhaité, mais les données n’existent pas sur le disque tant que vous ne les avez pas écrites. Toutes les lectures des zones non écrites renverront des zéros.
  2. Utilisation de la fonction SetFileValidData pour définir la longueur de données valide sans mettre à zéro le fichier en premier. Toutefois, en raison de problèmes de sécurité potentiels, cette commande nécessite des permissions élevées.

Je suis d’accord avec le dernier commentaire. J’expérimentais un pilote de minifiltre et capturais des IRP IRP_MJ_WRITE en rappel. Lorsque je crée ou écris dans le fichier à partir d’une application cmd ou d’une application win32, je peux voir les écritures arriver. Mais quand j’ai créé un fichier en utilisant la commande “fsutil file createnew …”, je ne vois aucune écriture. Je vois ce comportement sur win2k8 r2 sur le volume NTFS. Et je ne pense pas (pas sûr à 100%) que c’est un fichier clairsemé non plus. Il définit probablement les propriétés de taille dans MFT sans allouer de cluster. fsutil vérifie l’espace disponible, donc si la taille du fichier est supérieure à l’espace libre sur le disque, vous obtenez l’erreur 1.

J’ai également exécuté le programme FSTINGL_GET_RETRIEVAL_POINTERS sur le fichier et j’ai obtenu une extension pour toute la taille du fichier. Mais je crois qu’il obtient toutes les données

C’est quelque chose qui pourrait être

  • Ecrit en Assembleur (vitesse brute aveuglante)
  • Un code C / C ++ natif pour ce faire
  • Peut-être un appel système non documenté pour faire ceci ou un truc qui n’est documenté nulle part.

Les trois points ci-dessus pourraient avoir un facteur très important – quand on y pense, quand un code .NET est chargé, il est jit’ted par le runtime (Ok, le facteur temps ne serait pas perceptible si vous avez une machine ultra-rapide) – sur un pentium bas de gamme, il serait perceptible, charge lente).

Plus que probable, il aurait pu être écrit en C / C ++. Cela peut vous surprendre si cela a été écrit dans Assembler.

Vous pouvez le vérifier vous-même – examinez la taille du fichier de l’exécutable et comparez-le à un exécutable de .NET. Vous pourriez faire valoir que le fichier est compressé, ce dont je doute que ce serait et donc être enclin à l’exclure, Microsoft n’irait pas jusque-là, je compte avec les activités de compression des exécutables.

J’espère que cela répond à votre question, Cordialement, Tom.

fsutil n’est rapide que sur NTFS et exFAT, pas sur FAT32, FAT16 C’est parce que certains systèmes de fichiers ont une taille “initialisée” et supportent donc une initialisation rapide des fichiers. Cela réserve simplement les clusters mais ne les vide pas, car il note dans le système de fichiers qu’aucune donnée n’a été écrite dans le fichier et que les lectures valides renverraient toutes des tampons remplis de 00.