C# 如何处理 OpenFileDialog 文件
Posted
技术标签:
【中文标题】C# 如何处理 OpenFileDialog 文件【英文标题】:C# How to dispose of OpenFileDialog file 【发布时间】:2016-05-15 02:51:01 【问题描述】:我使用OpenFileDialog
获取图像的路径,然后在 WPF 应用程序中将其设置为我的图像源属性imgSelected.Source = new BitmapImage(new Uri(filenameSteg, UriKind.Absolute));
。
问题是,我需要稍后再次打开该文件,但我无法打开它,因为该文件正被另一个进程使用 (System.IO.IOException
-> The process cannot access the file
pathToFile because it is being used by another process.
).
稍后需要访问它的代码如下:
bitmapSource = JpegBitmapDecoder.Create(File.Open(filenameSteg, FileMode.Open),
BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames[0];
这个bitmapSource
用于将该图像提供给WriteableBitmap
,然后我从那里遍历像素。
有没有办法处理用 OpenFileDialog 打开的 File ?
我尝试强制转换为 IDisposable,使用 using 块等等,但这个东西是持久的。
编辑:
1 - 我试过这个(@ctacke 回答):
using (var stream = File.Open(filenameSteg, FileMode.Open))
bitmapSource = JpegBitmapDecoder.Create(stream, BitmapCreateOptions.None,
BitmapCacheOption.OnLoad).Frames[0];
但它仍然给我关于该进程已被另一个进程使用的错误,因为即使它会在之后被释放,我仍然试图打开与在@987654332 中打开的相同的文件 (filenameSteg
) @。 (或者至少,我是这么看的。)
2 - 然后我尝试了这个(基于@ctacke 推荐的link:
using (FileStream fileStream = new FileStream(filenameSteg+1, FileMode.Create))
MemoryStream memoryStream = new MemoryStream();
BitmapImage bi = new BitmapImage();
byte[] fileBytes = File.ReadAllBytes(filenameSteg);
memoryStream.Write(fileBytes, 0, fileBytes.Length);
memoryStream.Position = 0;
bi.BeginInit();
bi.StreamSource = memoryStream;
bi.EndInit();
bitmapSource = bi;
注意:请注意,我在这里请求filenameSteg +1
。那是因为我想测试我的方法的其余部分,所以我创建了一个文件副本并简单地将 1 添加到它的名称中。话虽这么说,当真正使用filenameSteg
时,它给了我关于已经在使用的相同错误,我再次怀疑我仍然要求打开之前在OpenFileDialog
中打开的相同图像。
3 - 我想到了另一种不需要我处理打开的图像的方法:
当我第一次在OpenFileDialog
中打开图像时,我将图像的字节数组存储在一个变量中,这样我就可以使用BitmapFactory
和字节数组创建WriteableBitmap
。
// This is in the OpenFileDialog. It is where I stock the image "pixels" in a byte array.
bytesArrayImage = File.ReadAllBytes(filenameSteg);
//And then later when I needed the WriteableBitmap, I used the byte array and the BitmapFactory
//imgSelected being the Image containing the image I opened in the OpenFileDialog, I used it's
//width and height
wb = BitmapFactory.New(Convert.ToInt32(imgSelected.Width),
Convert.ToInt32(imgSelected.Height)).FromByteArray(bytesArrayImage);
这种方法的问题在于,有些图片可以正常工作,我可以使用字节数组创建WriteableBitmap
并遍历它的像素,但在其他情况下它会给我一个AccessViolationException
说明:Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
。换句话说,试图绕过 dispose 问题让我陷入了另一个问题。
【问题讨论】:
【参考方案1】:你应该释放原始图像,像这样:
if(imgSelected.Source != null)
imgSelected.Source.Dispose;
imgSelected.Source = new BitmapImage(new Uri(filenameSteg, UriKind.Absolute));
接下来,File.Open
返回一个流,您需要显式释放它。
using(var stream = File.Open(filenameSteg, FileMode.Open))
var bitmapSource = JpegBitmapDecoder.Create(stream,
BitmapCreateOptions.None, BitmapCacheOption.OnLoad).Frames[0];
另请参阅:Load a BitmapSource and save using the same name in WPF -> IOException
【讨论】:
感谢@ctacke 的快速回复,我使用您提到的方法(使用 using 块获取流然后将其处理)和链接中的方法编辑了我的问题你提供的信息。在我试图绕过它之后,我也将当前状态放在了现在的位置。以上是关于C# 如何处理 OpenFileDialog 文件的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中,如何处理具有多个线程/任务但有条件的大型文本文件?
“私有”可见性修饰符 - 将 C# 转换为 VB 时如何处理差异?