Pourquoi dois-je fermer () un fichier en C #?

Je sais que cela peut paraître idiot, mais pourquoi le code suivant ne fonctionne-t-il que si je ferme () le fichier? Si je ne ferme pas le fichier, le stream entier n’est pas écrit.

Pas:

  1. Exécutez ce code lors du chargement du formulaire.
  2. Fermez le formulaire en utilisant la souris une fois qu’il est affiché.
  3. Le programme se termine.

L’object de fichier ne doit-il pas être vidé ou fermé automatiquement lorsqu’il sort du champ d’application? Je suis nouveau dans C #, mais je suis habitué à append des appels à Close () dans les destructeurs C ++.

// Notes: complete output is about 87KB. Without Close(), it's missing about 2KB at the end. // Convert to png and then convert that into a base64 encoded ssortingng. ssortingng b64img = ImageToBase64(img, ImageFormat.Png); // Save the base64 image to a text file for more testing and external validation. StreamWriter outfile = new StreamWriter("../../file.txt"); outfile.Write(b64img); // If we don't close the file, windows will not write it all to disk. No idea why // that would be. outfile.Close(); 

C # n’a pas de nettoyage déterministe automatique. Vous devez être sûr d’appeler la fonction de nettoyage si vous souhaitez contrôler son exécution. Le bloc using est le moyen le plus courant de le faire.

Si vous ne lancez pas l’appel de nettoyage vous-même, le nettoyage aura lieu lorsque le ramasse-miettes décide que la mémoire est nécessaire pour autre chose, ce qui peut prendre beaucoup de temps plus tard.

 using (StreamWriter outfile = new StreamWriter("../../file.txt")) { outfile.Write(b64img); } // everything is ok, the using block calls Dispose which closes the file 

EDIT: Comme le fait remarquer Harvey, bien que le nettoyage soit tenté lorsque l’object est collecté, cela ne garantit en rien le succès. Pour éviter les problèmes de références circulaires, le moteur d’exécution ne tente pas de finaliser les objects dans le “bon” ordre. FileStream peut donc déjà être mort au moment où le finaliseur StreamWriter s’exécute et tente de vider la sortie mise en mémoire tampon.

Si vous traitez des objects nécessitant un nettoyage, faites-le explicitement, en using (pour une utilisation localisée) ou en appelant IDisposable.Dispose (pour les objects à vie longue tels que les référents des membres de la classe).

Parce que Write () est mis en mémoire tampon et que le tampon est explicitement vidé par Close ().

Les stream sont des objects qui “gèrent” ou “gèrent” des ressources collectées non parasites. Ils (Streams) implémentent donc l’interface IDisposable qui, lorsqu’elle est utilisée avec “using”, garantit le nettoyage des ressources non gâchées. essaye ça:

 using ( StreamWriter outfile = new StreamWriter("../../file.txt") ) { outfile.Write(b64img); } 

Sans le #Fermer, vous ne pouvez pas savoir quand le descripteur de fichier sous-jacent sera correctement fermé. Parfois, cela peut être à l’arrêt de l’application.

Parce que vous utilisez un streamwriter et qu’il ne vide pas le tampon tant que vous n’avez pas fermé le script Close() . Vous pouvez indiquer que vous souhaitez que le rédacteur AutoFlush chaque fois que vous appelez écriture en définissant la propriété AutoFlush de streamwriter sur true.

Consultez la documentation. http://msdn.microsoft.com/en-us/library/system.io.streamwriter.aspx

Si vous voulez écrire dans un fichier sans “fermer”, je voudrais utiliser:

 System.IO.File 

Le cache du système d’exploitation écrit sur des périphériques en mode bloc afin de permettre au système d’exploitation d’améliorer ses performances. Vous forcez une écriture en vidant la mémoire tampon après une écriture de réglage de streamwriter sur autoflush.

Parce que les concepteurs C # clonaient Java et non C ++ malgré le nom.

À mon avis, ils ont vraiment manqué le bateau. La destruction de style C ++ à la sortie du scope aurait été tellement meilleure .

Il ne serait même pas nécessaire de libérer la mémoire pour être meilleur, il suffit d’exécuter automatiquement le finaliseur ou la méthode IDisposable.