解决了
我发现 GetNewFolderNameBasedOnDate 方法内部没有关闭文件。我已经修复了该方法,现在可以正常工作
我正在尝试使用 C# 中的 BackgroundWorker 进程将选定的文件从一个文件夹移动到另一个文件夹。这是我的 DoWork() 方法,用于确定是移动文件还是仅复制。我的 File.Move() 抛出异常“该进程无法访问该文件,因为它正被另一个进程使用”。我尝试了stackoverflow中线程中提到的不同方法。
private void FileProcessor_DoWork(object sender, DoWorkEventArgs e)
{
// Copy files
long bytes = 0;
string destSubFolder = String.Empty;
string destFile = string.Empty;
foreach (FileInfo file in oSettings.SourceFiles)
{
try
{
this.BeginInvoke(OnChange, new object[] { new UIProgress(file.Name, bytes, oSettings.MaxBytes) });
destSubFolder = GetNewFolderNameBasedOnDate(file);
//Create a new subfolder under the current active folder
string newPath = Path.Combine(oSettings.TargetFolder, destSubFolder);
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(newPath))
{
System.IO.Directory.CreateDirectory(newPath);
}
destFile = Path.Combine(oSettings.TargetFolder, destSubFolder, file.Name);
if (chkDeleteSourceFiles.Checked)
{
FileInfo f = new FileInfo(file.FullName);
if (f.Exists)
{
File.Move(file.FullName, destFile);
}
}
else
{
File.Copy(file.FullName, destFile, true);
}
//Thread.Sleep(2000);
}
catch (Exception ex)
{
UIError err = new UIError(ex, file.FullName);
this.Invoke(OnError, new object[] { err });
if (err.result == DialogResult.Cancel) break;
}
bytes += file.Length;
}
}
我也尝试删除“RunWorkerCompleted”方法中的文件。但没有解决问题。当它尝试删除列表中的最后一个文件时失败。
private void FileProcessor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Operation completed, update UI
ChangeUI(false);
foreach (FileInfo file in oSettings.SourceFiles)
{
File.Delete(file.FullName);
}
}
GetNewFolderNameBasedOnDate() 调用 GetDateTaken() 这是罪魁祸首。早些时候我没有使用 FileStream 对象,但使用Image myImage = Image.FromFile(filename);
了我不知道 Image.FromFile 锁定了文件。
private DateTime GetDateTaken(string fileName)
{
try
{
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
Image myImage = Image.FromStream(fs);
PropertyItem propItem = myImage.GetPropertyItem(36867);
DateTime dtaken;
//Convert date taken metadata to a DateTime object
string sdate = Encoding.UTF8.GetString(propItem.Value).Trim();
string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" ")));
string firsthalf = sdate.Substring(0, 10);
firsthalf = firsthalf.Replace(":", "-");
sdate = firsthalf + secondhalf;
dtaken = DateTime.Parse(sdate);
return dtaken;
}
}
catch (Exception ex)
{
return DateTime.Now;
}
}