c# - 如何删除文件锁? C#

标签 c# file file-io

所以我正在使用 C# 并正在制作一个注册系统。所以有一个添加图片的选项,我做了什么,我提示用户选择一个文件,然后该文件将被复制到目录文件夹,然后重命名为学生的录取编号。这是该浏览按钮的代码:

OpenFileDialog openDlg = new OpenFileDialog();
            openDlg.Filter = "All JPEG files (*.jpg; *.jpeg)| *.jpg; *.jpeg";
            string filter = openDlg.Filter;
            openDlg.Multiselect = false;
            openDlg.Title = "Open a JPG File";
            if (openDlg.ShowDialog() == DialogResult.OK)
            {                
                curFileName = openDlg.SafeFileName;
                string curFilePath = openDlg.FileName;

                openDlg.Dispose();

                string sourcePath = @curFilePath.Remove((curFilePath.Length - curFileName.Length));
                string targetPath = "@";

                mycon.Open();
                string cmdstr = "SELECT imageDirectory from userSettings WHERE ID = 1";
                cmd = new OleDbCommand(cmdstr, mycon);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    targetPath = (@dr["imageDirectory"].ToString());
                }
                dr.Close();
                mycon.Close();

                string sourceFile = Path.Combine(sourcePath, curFileName);
                string destFile = Path.Combine(targetPath, curFileName);

                File.Copy(sourceFile, destFile, true);

                newname = @destFile.Remove((destFile.Length - curFileName.Length)).ToString() + "\\" + (DateTime.Now.Year + "-" + textBox1.Text+".jpeg");

                if (File.Exists(newname) == true)
                {
                    pictureBox1.Image.Dispose();
                    try
                    {
                        File.Delete(newname);
                    }

                    catch (IOException ex)
                    {
                        MessageBox.Show(ex.ToString());
                        return;
                    }
                }

                File.Move(destFile, newname);

                photoPath = newname;
                pictureBox1.Image = Image.FromFile(photoPath);

问题是:

a.) 我有一个功能允许用户转到下一步,然后如果他想在最后一步中做一些更改,他可以返回并更新它。这里的问题是当他更改图片时,我收到错误消息“无法访问该文件,因为它正在被另一个进程使用”

b.) 当用户已经上传了一张图片然后返回主页时,当他决定再次注册时他将无法上传新图片,并显示错误信息:“文件不能因为它正在被另一个进程使用而被访问”。

两个错误都指向这里:

`File.Delete(newname);`

伙计们,我真的不知道该怎么做自昨晚以来我一直在寻找解决方案,但我看不到不会让我完全更改整个代码的解决方案。请帮助:(

最佳答案

你的代码是正确的,忽略关于代码味道的贬低。处理 PictureBox.Image 对于避免内存不足异常很重要。

此问题是由 Bitmap 类的一个实现细节引起的。当您打开图像文件时,该类会创建一个内存映射文件以将图像的像素数据映射到内存中。这是对大图像的重要优化,它将像素数据保留在页面文件之外。在 GDI+ 设计 15 年后,现代机器拥有大量 RAM 和磁盘空间,如今它并不那么重要。

然而,该内存映射文件会在该文件上创建一个锁。重要的是要防止任何其他进程弄乱文件数据并使文件的映射 View 无效。这就是您所看到的,尝试替换或删除文件不再有效。您可以通过创建位图的深拷贝来避免它,该副本在内存中包含所有像素数据并且不再使用该文件。像这样:

public static Bitmap LoadBitmapNolock(string path) {
    using (var img = Image.FromFile(path)) {
        return new Bitmap(img);
    }
}

请注意,使用此代码会显着增加 32 位版本 Windows 上大图像内存不足的几率。

关于c# - 如何删除文件锁? C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12879539/

相关文章:

java - AndroidLauncher 找不到 Assets ,但 DesktopLauncher 可以

php - 逐行读取大文件或将其行存储在数组中

java - 获取 Java 目录中最近 7 天内修改的所有文件

java - 如何从位置读取文本文件

c# - 在 .NET 3.5 下的 Unity3D 中使用 Simple Injector 1 进行属性注入(inject)

C# DependencyProperty - 对复杂类型使用默认属性

c# - 在 linq 结果中插入额外数据但不插入数据源或等待提交对上下文对象的更改

c - C 中的文件输入

c# - 是否可以在已经创建的实例上直接调用构造函数?

python - 在前一个文件之上读取文件