-1

解決済み

GetNewFolderNameBasedOnDate メソッドが内部的にファイルを閉じていないことがわかりました。私はその方法を修正し、現在は正常に機能しています

C# で BackgroundWorker プロセスを使用して、選択したファイルをあるフォルダーから別のフォルダーに移動しようとしています。ファイルを移動するか、単にコピーするかを決定する DoWork() メソッドを次に示します。私の File.Move() は、「別のプロセスで使用されているため、プロセスはファイルにアクセスできません」という例外をスローします。ここのスタックオーバーフローのスレッドで言及されているように、さまざまな方法を試しました。

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;
    }
}
4

2 に答える 2

0

私の推測では、OnChangeへのBeginInvoke呼び出しと、ファイルを保持している新しいUIProgress()オブジェクトです。UIProgressはファイルを開きますか?Invoke()を使用してみて、それが役立つかどうかを確認できます。

于 2012-07-20T20:32:13.410 に答える
0

新しい FileInfo オブジェクトを作成する代わりに、単純にして同じものを再利用してください。問題は、コード内の同じファイルへの複数の参照があり、それが削除できないことだと思われます。次のようにして動かしてみてください。

if (chkDeleteSourceFiles.Checked)
{
    if (file.Exists)
    {
        file.MoveTo(destFile);
    }
}
于 2012-07-20T20:07:39.777 に答える