Pourquoi l'Image.FromFile garder un descripteur de fichier ouvert, parfois?
Je fais beaucoup de traitement de l'image dans GDI+ dans .NET ASP.NET application.
J'ai souvent trouver que de l'Image.FromFile() est de garder un descripteur de fichier ouvert.
Pourquoi est-ce? Quel est le meilleur moyen d'ouvrir une image sans le descripteur de fichier sont conservées.
- NB: je ne fais rien de stupide comme garder l'Image de l'objet de traîner - et même si je l'était je woudlnt attendre le descripteur de fichier pour rester active
- Êtes-vous sûr que FromFile est en train de faire ça? Idiot, je sais, mais vous pouvez utiliser la poignée (Sysinternals utilitaire) pour vérifier que la poignée vient en effet de FromFile.
Vous devez vous connecter pour publier un commentaire.
Je suis passé par le même chemin que quelques autres affiches sur ce fil. Choses que j'ai noté:
L'Aide De L'Image.FromFile ne semblent imprévisibles sur quand elle libère le descripteur de fichier. L'appel de l'Image.Dispose() n'a pas libérer le handle de fichier dans tous les cas.
À l'aide d'un FileStream et de l'Image.FromStream méthode fonctionne, et libère la poignée sur le fichier si vous appelez dispose() sur l'objet FileStream ou enveloppez le tout en un à l'Aide de {} énoncé tel que recommandé par Kris. Toutefois, si vous essayez d'enregistrer l'Image de l'objet à un flux de données, l'Image.Enregistrer la méthode lève une exception "générique erreur s'est produite dans GDI+". Sans doute quelque chose dans la méthode Save veut connaître l'origine de fichier.
Steven approche a fonctionné pour moi. J'ai été en mesure de supprimer l'origine de fichiers avec l'Image de l'objet en mémoire. J'ai aussi été en mesure d'enregistrer l'Image à la fois un flux et d'un fichier (j'avais besoin de faire ces deux choses). J'ai aussi été en mesure d'enregistrer sur un fichier avec le même nom que l'origine de fichier, quelque chose qui est documenté comme pas possible si vous utilisez l'Image.La méthode FromFile (je trouve cela bizarre car c'est sûrement la plus probable de cas d'utilisation, mais bon.)
Donc, pour résumer, ouvrez votre Image comme ceci:
Puis libre à vous de le manipuler (et à l'origine de fichier) que vous voyez l'ajustement.
J'ai eu le même problème et a eu recours à la lecture du fichier en utilisant
return Image.FromStream(new MemoryStream(File.ReadAllBytes(fileName)));
Image.FromFile garde le descripteur de fichier ouvert jusqu'à ce que l'image est éliminé. À partir de la MSDN:
"Le fichier reste verrouillé jusqu'à ce que l'Image est disposé."
Utilisation De L'Image.FromStream, et vous n'aurez pas le problème.
Edit: (un an et un peu plus tard)
Le code ci-dessus est dangereux car il est imprévisible, à un certain point dans le temps (après la fermeture de la filestream) vous peut obtenir le redouté "générique erreur s'est produite dans GDI+". Je voudrais le modifier pour:
Assurez-vous de Disposer correctement.
L'aide d'expression est un raccourci pour
@Rex dans le cas de l'Image.Jetez les appels GdipDisposeImage extern /Win32 natif d'appel dans il Dispose().
IDisposable est utilisé comme un mécanisme pour libérer des ressources non managées (Qui descripteurs de fichiers sont)
J'ai aussi essayé tous vos conseils (ReadAllBytes, FileStream=>FromStream=>newBitmap() pour faire une copie, etc.) et ils ont tous travaillé. Cependant, je me demandais si vous pouviez trouver quelque chose de plus court, et
apparaît au travail, aussi, car il dispose de la poignée de fichier ainsi que l'original de l'Image-objet et crée une nouvelle image-objet, qui est indépendant du fichier d'origine et, par conséquent, peuvent être enregistrées dans un flux de données ou de fichiers sans erreurs.
Je voudrais faire pointer mon doigt par le Garbage Collector. Laissant autour n'est pas vraiment la question si vous êtes à la merci de la Collecte des Ordures.
Ce gars avait un semblable plainte... et il a trouvé une solution de contournement de l'utilisation d'un objet FileStream plutôt que de charger directement à partir du fichier.
...
Il semble comme un hack...
Comme mentionné précédemment, le travail Microsoft autour de causes d'un GDI+ erreur après plusieurs images ont été chargées. Le VB de solution pour moi, comme mentionné ci-dessus par Steven est
Je viens de rencontré le même problème, lorsque j'étais en train de fusionner plusieurs, une seule page des fichiers TIFF dans un multipart image TIFF. J'avais besoin d'utiliser
Image.Save()
et de l'Image.SaveAdd()`: https://msdn.microsoft.com/en-us/library/windows/desktop/ms533839%28v=vs.85%29.aspxLa solution dans mon cas était de faire appel ".Dispose()" pour chacune des images, dès que j'ai fait avec eux: