comment prévenir l'Image.FromFile() la méthode de verrouiller le fichier
Je suis à l'aide de code suivant pour mettre au format JPG dans un DataGridView
l'Image de la cellule.
If strFileName.ToLower.EndsWith(".jpg") Then
Dim inImg As Image = Image.FromFile(strFileName)
DataGridView4.Rows.Add()
DataGridView4.Rows(DataGridView4.Rows().Count - 1).Cells(0).Value = inImg
End If
Le problème est que j'ai besoin d'enregistrer ce fichier dans le programme, mais je reçois le message que le fichier est être utilisé par un autre programme.
J'ai donc essayé d'ajouter inImg.Dispose()
avant la fin si, mais le programme ne marche pas afficher les images plus dans le DataGridView
.
Comment puis-je ajouter des images dans le DataGridView
sans les bloquer?
grâce
Quand vous dites "enregistrer", vous dire de faire quelque chose avec le fichier qui est incompatible avec l'avoir ouvert par un programme? (exemples: déplacer, supprimer, renommer, etc.)?
OriginalL'auteur sharkyenergy | 2013-08-15
Vous devez vous connecter pour publier un commentaire.
Lorsque vous utilisez le
Image.FromFile(strFileName)
méthode pour créer leImage
, la méthode verrouille le fichier jusqu'à ce que vous relâchez leImage
. La raison exacte est expliqué ci-dessous. Et c'est pourquoi vous ne pouvez pas avoir accès à plus d'une seule fois pour le même fichier image avec cette méthode.Au contraire:
FileStream
ou unMemoryStream
que vous créer à partir du fichier image.Possibles de la mise en œuvre d'une coutume
SafeImageFromFile
méthode qui n'a pas de verrouiller le fichier image:Ou
Utilisation
Remarque importante
Ici, j'ai créer le
FileStream
ou unMemoryStream
à l'aide d'unUsing
déclaration assurez-vous que le flux est libéré. Il fonctionne très bien sur mon système et il semble que cela fonctionne pour vous aussi, si MSDN dit à propos de Image.FromStream(stream) méthode:La raison de cette phrase est expliquer ici: KB814675 Bitmap et une Image de constructeur dépendances
Afin de connaître le code ci-dessus pourrait générer
GDIexceptions
parce que de libérer le flux à l'aideUsing
. Il pourrait se produire lorsque vous enregistrez l'image à partir du fichier ou lors de la création de l'image. À partir de ce fil Chargement d'une image à partir d'un flux sans maintenir le flux ouvert et Hans Passant de commentaire elles correction de plusieurs problèmes avec indexé formats de pixel dans la version Vista de gdiplus.dll., il ne se produit que sur XP.Pour éviter cela, vous devez garder le flux ouvert. Les méthodes serait:
Ou
Mais ces derniers ont des méthodes de certains inconvénient, comme ne pas libérer le flux de données (problème de mémoire) et ils violent la règle CA2000 Disposer les objets avant de perdre portée .
La base de connaissances l'article donne quelques solutions de contournement:
Ici est une mise en œuvre de la Non-Indexé la création de l'Image, fondée sur l'article et cette réponse https://stackoverflow.com/a/7972963/2387010 Votre meilleur pari est de créer un pixel-réplique parfaite de l'image, si YMMV (avec certains types d'images, il peut être plus qu'une image, ou vous pouvez copier les données de palette). Mais pour la plupart des images, cela fonctionne:
Quelqu'un a indiqué que ce qui est important, c'est que le
FileStream
est ouvert en mode lecture (FileAccess.Read
).Vrai, mais il fait plus de sens si vous n'utilisez pas
Using
déclaration et si vous ne relâchez pas le flux, ou en multi-threads contexte:FileAccess.Write
est inapproprié, etFileAccess.ReadWrite
n'est pas nécessaire, mais ouvrir le flux avecFileAccess.Read
mode ne l'empêchera pas d'avoir unIO.Exception
si un autre programme (ou la vôtre, en multi-threads contexte) a ouvert le fichier avec un autre mode deFileAccess.Read
.Si vous voulez être en mesure pour afficher l'image et en même temps être en mesure d'enregistrer les données dans le fichier, Puisque vous n'avez pas de verrouiller le fichier avec ces méthodes, vous devriez être en mesure de sauver l'image (supprimer/remplacer le fichier précédent) à l'aide de la
Image.Save
méthode.merci, mais que voulez-vous faire ensuite? je ne peux pas dire que le programme ne sera pas utilisées sur des systèmes plus anciens.. que feriez-vous pour afficher l'image et en même temps être en mesure d'enregistrer les données dans le fichier? merci!!!!
BEAUCOUP plus de sens! merci beaucoup Chris! la réponse est tout simplement PARFAIT!
lol.. désolé de na pas le lire attentivement! merci!
J'ai modifié le
g.DrawImage(b, Point.Empty)
comme ceg.DrawImage(b, 0, 0, b.width, b.height)
parce que mon image était estompée.OriginalL'auteur Chris
@ Chris: Ouverture d'environ 100 grandes (3400x2200) des images avec votre code final, j'ai reçu un argument non valide crash sur
[img = new bitmap(...]
, j'ai vu cela avant d'ouvrir une image de la taille de zéro, mais ce n'était pas le cas ici. J'ai ajoutéfs.dispose
et ouvert avec succès des milliers d'images de la même taille que le même jeu que le premier test sans problème. Je suis intéressé par vos commentaires sur ce.appel
fs.Dispose()
ne changera rien ici, parce que la ligne suivante (End Using
) appelle automatiquementfs.Dispose()
.OriginalL'auteur Alan
Cela fonctionne sans problème, a couru 4189 images 3400x2200 (deux fois) sans problème, cela déplace le filestream à l'extérieur de la fonction et de la ré-utilise. Im de la fermeture du fichier à libérer le verrou d'écriture. Im pointant un picturebox à cette image dans une boucle pour mon test.
OriginalL'auteur Alan
Après des recherches sur internet pour longtemps, j'ai découvert que je peux utiliser ce code sans erreur.
OriginalL'auteur Newby Programmer
J'ai rencontré la même situation et a utilisé ce code:
Je n'ai pas disposer de flux de mémoire, car elle permet d'enregistrer l'image plus tard, en utilisant exactement le même codage que le fichier d'origine, à l'aide de ce code:
OriginalL'auteur Jean-Xavier Bardant