无法删除在列表视图中显示的图像文件

4
在我的列表视图中,我展示了某个文件夹中小图片的缩略图。我按照以下方式设置了列表视图:
var imageList = new ImageList();
foreach (var fileInfo in dir.GetFiles())
{
    try
    {
        var image = Image.FromFile(fileInfo.FullName);
        imageList.Images.Add(image);
    }
    catch
    {
        Console.WriteLine("error");
    }
}

listView.View = View.LargeIcon;
imageList.ImageSize = new Size(64, 64);
listView.LargeImageList = imageList;

for (int j = 0; j < imageList.Images.Count; j++)
{
    var item = new ListViewItem {ImageIndex = j, Text = "blabla"};
    listView.Items.Add(item);
}

用户可以在列表视图中右键单击图像以将其删除。我从列表视图中将其删除,然后想要从文件夹中删除此图像。现在我收到了文件正在使用的错误。当然,这是合理的,因为imagelist正在使用该文件。
我尝试首先从imagelist中删除图像,但我仍然无法解除文件锁定。
有人能告诉我我做错了什么吗?
谢谢!
3个回答

6

您需要将文件加载到MemoryStream中,方法如下:

var image = Image.FromStream(new MemoryStream(File.ReadAllBytes(fileInfo.FullName)));

这样做,文件只会被读取一次,并且不会保持锁定状态。

编辑

你正在将图片加载到ImageList中。由于ImageList会复制它的图像,因此你应该立即处理掉原始图片,就像这样:
using (var image = Image.FromFile(fileInfo.FullName))
    imageList.Images.Add(image);

@Enrico:这样做非常浪费机器资源。你只是在将图像添加到ImageList后忘记调用image.Dispose()了。 - Hans Passant
@Hans:ImageList 会复制图片吗? - SLaks
它将位图克隆以匹配ImageList的大小和颜色深度。 - Hans Passant

1
使用GetThumbnailImage方法获取缩略图,然后释放图片:
var image = Image.FromFile(fileN);

Image imgThumb = image.GetThumbnailImage(100, 100, null, new IntPtr());

imageList1.Images.Add(imgThumb);

image.Dispose();

listView1.LargeImageList = imageList1;

现在您可以删除该文件:
File.Delete(FileN);

1
图片需要被处理掉才能解锁文件。在从图像列表中移除图像对象后,尝试调用Dispose。只要您有图像对象的引用并且GC没有收集它,它就会保持锁定状态。调用Dispose应该强制其放弃句柄并导致文件解锁。在此之前,您还必须确保应用程序没有CopyHandle或以其他方式获得对图像资源的第二个引用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接