删除另一个进程正在使用的文件
Posted
技术标签:
【中文标题】删除另一个进程正在使用的文件【英文标题】:Delete a file being used by another process 【发布时间】:2021-08-23 13:18:39 【问题描述】:我正在尝试以编程方式删除一个文件,但该文件显然正被另一个进程(恰好是我的程序)使用。基本上,程序通过使用 FromUri 从文件夹加载图像以创建位图,然后将其加载到图像数组中,该数组又成为堆栈面板的子项。效率不高,但很管用。
我已尝试清除堆栈面板的子项,并使数组中的图像为 null,但我仍然收到 IOException,告诉我该文件正在被另一个进程使用。
还有其他方法可以从我的应用程序进程中删除文件吗?
【问题讨论】:
您要处理图像吗?将它们设置为 null 意味着它们的句柄在被垃圾回收之前不会关闭。 显示加载它们的代码。如果你对他们有悬空的根,他们仍然是开放的。 【参考方案1】:可能是垃圾回收问题。
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
File.Delete(picturePath);
【讨论】:
令人讨厌(!?)这确实有效。尝试了其他所有方法,包括 retry 模式,但这两行就是这样做的。 它也帮助了我。感谢您的解决方案。 :) 这对我也有帮助。谢谢 谢谢!它也对我有帮助! 如果这个答案对你有用,那可能是因为你没有关闭FileStream
。垃圾收集器会调用终结器~FileStream()
,后者又会调用自己的Dispose()
方法,进而释放文件句柄(参见source code。)【参考方案2】:
为了在加载后释放图像文件,您必须通过设置BitmapCacheOption.OnLoad
标志来创建图像。一种方法是:
string filename = ...
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = new Uri(filename);
image.EndInit();
虽然设置 BitmapCacheOption.OnLoad
可以在从本地文件 Uri 加载的 BitmapImage 上工作,但这是 afaik 无处记录的。因此,一种可能更好或更安全的方法是从 FileStream 加载图像,方法是设置 StreamSource
属性而不是 UriSource
:
string filename = ...
BitmapImage image = new BitmapImage();
using (var stream = File.OpenRead(filename))
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
【讨论】:
谢谢,这解决了我的问题。但是,我想知道,从文件中创建 BitmapImage 是否有任何内存影响?我想我会把它作为一个单独的问题发布。 就是这个!我整个早上都在搞乱图像缩放程序,这就是解决方法。使用new URI(path)
是问题,替换为OpenRead
流,并且已修复。【参考方案3】:
另一种方法是删除文件。使用 FileStream 类加载文件并发布文件 通过 stream.Dispose(); 它永远不会给你异常“该进程无法访问文件'',因为它正在被另一个进程使用。”
using (FileStream stream = new FileStream("test.jpg", FileMode.Open, FileAccess.Read))
pictureBox1.Image = Image.FromStream(stream);
stream.Dispose();
// delete your file.
File.Delete(delpath);
【讨论】:
显然,如果您稍后尝试操作、克隆甚至保存图像,这将产生异常。【参考方案4】:var uploadedFile = Request.Files[0]; //Get file
var fileName = Path.GetFileName(uploadedFile.FileName); //get file name
string fileSavePath = Server.MapPath(fileName); //get path
uploadedFile.SaveAs(fileSavePath); //saving file
FileInfo info = new FileInfo(fileSavePath);//get info file
//the problem ocurred because this,
FileStream s = new FileStream(fileSavePath, FileMode.Open); //openning stream, them file in use by a process
System.IO.File.Delete(fileSavePath); //Generete a error
//problem solved here...
s.Close();
s.Dispose();
System.IO.File.Delete(fileSavePath); //File deletad sucessfully!
【讨论】:
【参考方案5】:我有类似的问题。唯一的区别是我使用的是绑定(MVVM 模式)。没有任何效果,然后我删除了所有内容并尝试使用 Binding Mode=OneWay
和 GC.Collect()
,然后调用 File.Delete(path)
,它终于奏效了。
【讨论】:
【参考方案6】:我有同样的问题。我遇到的问题是 openFileDialog 和 saveFileDialog 具有以下设置:
MyDialog.AutoUpgradeEnabled = false;
我把那行注释掉了,它已经解决了。
【讨论】:
以上是关于删除另一个进程正在使用的文件的主要内容,如果未能解决你的问题,请参考以下文章
kafka报错:timeindex :另一个程序正在使用此文件,进程无法访问