【语言-c#】文件被占用如何解除

1、加载文件后,删除文件时提示如下

文件“..jpg”正由另一进程使用,因此该进程无法访问此文件。

背景

C# 中使用Image.FromFile(string path) 使用 System.IO.File.Delete(string path) 提示该文件正在被另一进程使用XXX的问题,是因为对应的文件在一直使用中 ,其生成的 Image 对象被 Disponse() 前都不会被解除锁定,这就造成了此问题,就是在这个图形被解锁前无法对图像进行操作(比如删除,修改等操作)。

解决方案


方法1:如果 Image 对象不需要保存在程序内存中,可以在进行删除、修改等操作之前将 Image 对象销毁
 

System.Drawing.Image image = System.Drawing.Image.FromFile(filePath);
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(image);
image.Dispose();

方法2:如果 Image 对象需要保存在程序内存中,将从文件加载的 Image 绘制到程序内存中的 Image 上,然后将 从文件加载的 Image 对象销毁。

System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);
System.Drawing.Image bmp = new System.Drawing.Bitmap(img.Width, img.Height, img.PixelFormat);

System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
g.DrawImage(img, 0, 0);
g.Flush();
g.Dispose();
img.Dispose();


方法3:以文件流的形式加载文件,加载完后关闭文件,然后将文件流转换成 Image 对象

System.IO.FileStream fs = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read);

int byteLength = (int)fs.Length;
byte[] fileBytes = new byte[byteLength];
fs.Read(fileBytes, 0, byteLength);

//文件流关閉,文件解除锁定
fs.Close();

 MemoryStream mStream = new MemoryStream(fileBytes);
Image image = Image.FromStream(mStream);


因为 FromStream 方法参数应用的流必须一直保持打开,故而代码中有一个文件流是向MemeoryStream流的转换,从而可以关闭文件流,保持 MemoryStream 流的打开状态。在不用 mStream 时关闭。
mStream.Close();

2、文件被占用强制删除类

 public void WipeFile(string filename, int timesToWrite)
{
    try
    {
        if (System.IO. File.Exists(filename))
        {
            //设置文件的属性为正常,这是为了防止文件是只读
            System.IO.File.SetAttributes(filename, System.IO.FileAttributes.Normal);
            //计算扇区数目
            double sectors = Math.Ceiling(new System.IO.FileInfo(filename).Length / 512.0);
            // 创建一个同样大小的虚拟缓存
            byte[] dummyBuffer = new byte[512];
            // 创建一个加密随机数目生成器
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            // 打开这个文件的FileStream
            System.IO.FileStream inputStream = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            for (int currentPass = 0; currentPass < timesToWrite; currentPass++)
            {
                // 文件流位置
                inputStream.Position = 0;
                //循环所有的扇区
                for (int sectorsWritten = 0; sectorsWritten < sectors; sectorsWritten++)
                {
                    //把垃圾数据填充到流中
                    rng.GetBytes(dummyBuffer);
                    // 写入文件流中
                    inputStream.Write(dummyBuffer, 0, dummyBuffer.Length);
                }
            }
            // 清空文件
            inputStream.SetLength(0);
            // 关闭文件流
            inputStream.Close();
            // 清空原始日期需要
            DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0);
            System.IO.File.SetCreationTime(filename, dt);
            System.IO.File.SetLastAccessTime(filename, dt);
            System.IO.File.SetLastWriteTime(filename, dt);
            // 删除文件
            System.IO.File.Delete(filename);
        }
    }
    catch (Exception)
    {
    }
}

3、文件被另一进程占用

Download Download Handle (418 KB)

string fileName = @"c:\aaa.doc";//要检查被那个进程占用的文件
Process tool = new Process();
tool.StartInfo.FileName = "handle.exe";//占用文件的进程
tool.StartInfo.Arguments = fileName+" /accepteula";
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();          
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();

string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
foreach(Match match in Regex.Matches(outputTool, matchPattern))
{
    Process.GetProcessById(int.Parse(match.Value)).Kill();
}

 

你可能感兴趣的:(语言-c#)