所以我正在使用 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/