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#中的错误代码

“私有”可见性修饰符 - 将 C# 转换为 VB 时如何处理差异?

如何处理C#的HttpWebResponse的GetResponse中的超时异常

C# 中的异常处理 - 如何处理?

c# foreach块程序如何处理ListView?