12
votes

Comment vous assurer qu'un fichier a été enregistré de manière permanente sur USB, lorsque l'utilisateur n'utilise pas «Supprimer en toute sécurité le matériel»?

Lorsque je sauvegardez un fichier sur une USB dans mon application Delphi, comment puis-je vous assurer que le fichier est réellement enregistré (définitivement) enregistré sur la clé USB, lorsque "Supprimer en toute sécurité le matériel" n'est pas effectué (particulièrement oublié à utiliser)? < BR> Dire à notre client d'utiliser la fonction Windows "Supprimer en toute sécurité le matériel" ne fonctionne pas.
Existe-t-il une commande Windows API pour affleurer le tampon, de sorte que toutes les données sont écrites de manière permanente sur le lecteur USB?


4 commentaires

Pour quiconque a voté pour fermer comme "non liée à la programmation", veuillez relire la question.


Pareil ici. La question est très liée à la programmation.


Je n'ai jamais eu de perte de données que je peux attribuer à la suppression d'un périphérique de stockage USB sans effectuer "Supprimer en toute sécurité du matériel". Je vous assure que les opérateurs de copie de fichier sont terminés (la boîte de dialogue "Copier les fichiers" disparaît). Suis-je extrêmement chanceux?


Les: oui. J'ai perdu des données beaucoup de fois ...


3 Réponses :


2
votes

Quoi qu'il arrive, vous pouvez débrancher l'appareil vous-même, je veux dire par programme. Ensuite, vous serez totalement sûr qu'ils ont supprimé l'appareil correctement.

Regardez les réponses de cette question: Safe-Supprimer-USB -Drive-with-win32-API . surtout Ce lien vers un article MSDN KB donné dans la réponse.


4 commentaires

Mais que si l'utilisateur ne veut pas supprimer le lecteur USB?


L'utilisateur retire déjà la clé USB, je ne pense pas qu'il en ait plus besoin. Plus sérieusement, s'il attendait plus de temps à utiliser le lecteur, le fichier se retrouverait écrit sur le disque (le fichier ne contient pas de cache pour toujours). (Je traite tous les jours avec ce genre de client, plus il est simple pour eux, mieux c'est pour tout le monde. Dites-leur qu'ils ne peuvent pas utiliser le lecteur, c'est simple; dites-leur qu'ils doivent aller à "Supprimer en toute sécurité le matériel", C'est trop. Je peux parier que notre op a déjà du code pour détecter automatiquement l'insertion de lecteur USB et la copie du fichier nécessaire à un chemin prédéterminé)


Adrien, nous savons seulement que l'utilisateur retire le lecteur parfois . Nous ne savons pas que l'utilisateur TOUJOURS supprime le lecteur après la sauvegarde. Nous ne savons pas non plus si le lecteur est utilisé pour des choses autres que ce programme.


@ROB: Vous avez raison, je faisais des hypothèses basées sur ma propre expérience personnelle ... mon mauvais.



11
votes

Lorsque vous ouvrez le fichier, spécifiez "écriture" (fichier_flag_write_through drapeau à Createefile ()). Cela obligera le système d'exploitation à écrire directement le fichier. Il peut toujours être dans le cache du système d'exploitation d'accélérer les lectures ultérieures, mais ce n'est pas un problème pour vous.

Si vous voulez affleurer des tampons de fichier, il y a bien sûr toujours flushfilebuffer ()


3 commentaires

Lorsque j'utilise des flushfilebuffers (), puis-je être sûr que le fichier est stocké physiquement sur le lecteur USB? Donc, cela ne disparaît pas, après "incontrôlé", débranchez-vous?


@max: Oui, tant qu'il y a suffisamment de temps entre l'appel aux flushfilebuffers () et l'élimination de l'écriture physique. IOW, si vous essayez d'écrire un fichier de 2 Go sur le disque USB, appelez les flushfilebuffers (), puis + instantanément + retirez le lecteur, il ne peut toujours pas être complètement écrit - il n'y a tout simplement pas de temps suffisant pour terminer l'opération d'écriture réelle. Vous devez éduquer vos utilisateurs sur la manière de supprimer en toute sécurité le lecteur ou d'attendre au moins que votre application leur indique qu'ils peuvent le supprimer; Votre application peut comprendre combien de temps cela doit attendre avant de leur donner ça ok.


Ken, vous le faites ressembler à des flushfilebuffers revenir avant qu'il ne finisse en réalité de rincer les tampons de fichiers. Est-ce exact? Si oui, alors Comment si le programme doit comprendre combien de temps il doit attendre?



4
votes

Voici une fonction que j'ai utilisée pour affleurer des données sur un lecteur USB avant de l'éjecter de manière programmatique. Cette fonctionnalité de clones de Utilitaire "Sync" de Mark Russinovich "Sync" . Je n'ai eu aucun problème avec ce code et il est exécuté sur beaucoup de systèmes depuis quelques années.

La partie la plus pertinente de ce code est l'appel à Flushfilebuffer . P>

function FlushToDisk(sDriveLetter: string): boolean;
var
  hDrive: THandle;
  S:      string;
  OSFlushed: boolean;
  bResult: boolean;
begin
  bResult := False;
  S := '\\.\' + sDriveLetter + ':';

  //NOTE: this may only work for the SYSTEM user  
  hDrive    := CreateFile(PAnsiChar(S), GENERIC_READ or
    GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
    OPEN_EXISTING, 0, 0);
  OSFlushed := FlushFileBuffers(hDrive);

  CloseHandle(hDrive);

  if OSFlushed then
  begin
    bResult := True;
  end;

  Result := bResult;
end;


4 commentaires

C'est pour affleurer tous les fichiers ouverts sur le volume. Si Max ne concerne que les fichiers écriture de son programme, et non avec d'autres fichiers que l'utilisateur peut écrire sur le lecteur par d'autres moyens, il peut probablement simplement rincer les poignées à ses fichiers au lieu de rincer le volume entier et Il n'aurait donc pas besoin de privilèges administratifs.


Il est presque impossible de garantir qu'il n'y aura pas de corruption. Le disque flash peut être retiré à tout moment. Je pense que la réponse de Msalters est plus correcte. Je suis d'accord avec Rob, c'est large.


Pourquoi ce code utilise-t-il 3 Vars (Osflushed, Bresult and Résultat) quand un seul semble faire le travail?


@Embarbosa, bon point. J'ai ajouté cela principalement pour plus de clarté, pas comme un exemple de la manière la plus concise de le faire.