我正在尝试从网站下载图像并将其放入图片框中。
// response contains HttpWebResponse of the page where the image is
using (Stream inputStream = response.GetResponseStream()) {
using (Stream outputStream = File.Open(fileName, FileMode.Create)) {
byte[] buffer = new byte[4096];
int bytesRead;
do {
bytesRead = inputStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
response.Close();
之后,下载的图像被分配到一个PictureBox,比如:
if (imageDownloaded) {
pictureBox1.Image = Image.FromFile(filePath);
}
这一切第一次运行起来很有魅力,但第二次运行代码时,我得到了System.IO.IOException:"附加信息:进程无法访问文件…(文件路径)…,因为它正被另一个进程使用。"。我不知道为什么。。。
我看了其他4个线程,比如这一个,但它们基本上强调了关闭流的必要性,我确实这样做了,所以它们都没有帮助我
在你建议使用pictureBox1.Load()
之前,我不能,因为我需要下载图像进行进一步开发。
EDIT 1:实际上,我已经尝试过在执行上面的代码之前放置pictureBox1.Image = null
来处理图像。它仍然给了我一个例外。
Image.FromFile
文档状态:
该文件保持锁定状态,直到
Image
被释放。
因此,您也需要处理您的Image
,以便能够覆盖该文件。
尝试在图像上使用Clone
方法并处理原始Image
。
这件事与Image.FromFile有关。如果我们阅读文档,会注意到:
在释放图像之前,文件一直处于锁定状态。
这在很大程度上解释了你的行为。
要解决此问题,您可能需要创建映像的副本,并将它分配给PictureBox
。
来自MSDN:
在释放图像之前,文件一直处于锁定状态。
这意味着它是PictureBox
保持文件打开。
你有两个选择:
-
在写入新文件之前先处理
PictureBox
映像。 -
下载文件,制作一份副本,并将副本加载到
PictureBox
中——这允许您自由地重写下载的文件。
我将是这里的反向者。:)
虽然克隆/复制映像可以解决异常,但它提出了一个不同的问题:为什么要为新映像覆盖到同一个文件?
在我看来,更好的方法是将后续文件下载到不同的文件名(如果它们真的是不同的文件),或者简单地重用已经下载的文件,而不是再次访问网络(如果只是对同一文件的新请求)。
即使您想重复下载同一个文件(也许您希望实际的文件内容会发生变化),您仍然可以下载到一个新名称(例如,在文件名后添加一个数字,使用本地文件名的GUID等)