C# - 无法关闭文件,导致文件在另一个进程中被使用'例外

时间:2015-12-30 18:38:16

标签: c# file

我有一个程序可以搜索给定路径中的文件夹,并拉出文件夹或其中任何子文件夹中的任何文件的路径。 从这里开始,它使用单个文件路径来创建名为ImageData的自定义类的对象。处理此问题的方法如下所示:

public void saveLatestImages(string chosenPath)
{
    //if there is a Pictures folder
    if (Directory.Exists(chosenPath))
    {
        //get number of files in folder
        int fileCount = Directory.GetFiles(chosenPath).Count();

        //more than one file in folder
        if (fileCount > 0)
        {
            //create data structures to store file info
            //filePaths holds path of each file represented as a string
            string[] filePaths = Directory.GetFiles(chosenPath);

            //for each file in Pictures...
            for (int index = 0; index < fileCount; ++index)
            {
                //get name of image at current index
                imageName = filePaths[index];
                //separate the part relating to the patient name (everything before (DD/MM/YYYY))
                string subSpecifier = imageName.Split('\\').Last();
                subSpecifier = subSpecifier.Split('_')[0];
                //add to root directory to form subfolder name
                subDirectory = Path.Combine(rootDirectory, subSpecifier);

                //subdirectory name formulated, check for pre-existing
                //subfolder does not exist
                if (!Directory.Exists(subDirectory))
                {
                    //create it
                    Directory.CreateDirectory(subDirectory);
                }
                //otherwise, file will be added to existing directory

                //take everything from end and folder\file division to get unique filename
                string fileName = imageName.Split('\\').Last();
                //add this to the existing subDirectory
                fileName = Path.Combine(subDirectory, fileName);

                //copy the image into the subfolder using this unique filename
                File.Copy(imageName, fileName, true); //true gives instruction to overwrite any existing file with the same path

                //construct new instance with created filename
                imageData.Add(new ImageData(fileName));

            }
        }
    }
}

到目前为止,这么好。 当ImageData创建的PictureBox对象显示在ImageData上时(使用Bitmap属性),问题就出现了。当此图像在图片框上时,可通过按钮获得许多选项。 例如,有一个按钮可以从图片框中删除private void btnDeleteImage_Click(object sender, EventArgs e) { /////////////////////////////////////////////////////////////////////////////////// //imageData is List<ImageData> that contains all ImageData objects currently in use //imageSlider is the PictureBox where the images are displayed///////////////////// /////////////////////////////////////////////////////////////////////////////////// //identify image currently on picturebox Image displayImage = imageData[displayImageIndex()].getThumbnailImage(); //get the file path of this image string displayImagePath = imageData[displayImageIndex()].getImagePath(); //move to next or previous image in list //then remove image that was just viewed //current image not last in list if (!(imageSlider.Image.Equals(imageData.Last().getThumbnailImage()))) { displayImage = imageData[displayImageIndex() + 1].getThumbnailImage(); //display the next image in the list imageSlider.Image = displayImage; //delete the image just moved on from from list imageData.RemoveAt(displayImageIndex() - 1); //delete the file path at this index in the paths list File.Delete(displayImagePath); } //current image is last in list else { displayImage = imageData[displayImageIndex() - 1].getThumbnailImage(); //display previous image in list imageSlider.Image = displayImage; //delete the image just moved on from from list imageData.RemoveAt(displayImageIndex() + 1); //delete the file path at this index in the paths list File.Delete(displayImagePath); <--- ////ERROR OCCURS//// } //check for prior and successive elements in list checkFirstLast(displayImage); updateImageInfo(); } 对象并删除文件。 这是使用以下方法完成的:

File.Delete()

FileStream命令上,出现异常以通知我无法访问该文件,因为该文件正由另一个进程使用&#39;。

基本上,文件在进入程序时会打开,并且永远不会关闭。这意味着当我尝试访问要删除的文件(或使用它执行其他操作)时,这不能像程序当前那样完成。 我知道如果我使用.Close()对象,那么一旦对象完成,我就可以调用FileStream方法。但是看到所有文件访问都是使用字符串变量完成的,然后用于创建图像,似乎没有一种等效的方法可供我使用。

有没有人知道实现此行为的任何其他方法?如果无法做到这一点,是否可以使用{ "_id": { "$oid": "567019357a5c390d040cbbc2" }, "EmailAddress": "joejane@myco.com", "SubscriptionSet": [ { "SubscriptionId": 586102, "SeatState": "ASSIGNED" }, { "SubscriptionId": 588972, "SeatState": "ASSIGNED" } ], "DisplayName": "Joe Jane", "SubscriberState": "ACTIVE" } 等方式管理图像文件?

关于从这里去哪里的任何建议都会很棒。

谢谢, 标记

2 个答案:

答案 0 :(得分:1)

通常的规范是 -

  • 创建暂存文件夹。像临时文件夹
  • 在那里制作文件的副本
  • 显示该临时文件中的图像
  • 为每个操作制作副本(1.jpg,2.jpg)
  • 最后完成后,将最新的最终文件复制回原始文件夹
  • 删除暂存文件夹

优势 -

  • 原始数据永不丢失
  • 意外腐败非常少
  • 易于撤消操作
  • 如果您无法立即删除暂存文件夹,则可以使用后台作业

答案 1 :(得分:1)

正如我的评论中所述,您可能正在使用the constructor that takes a string(文件名)在Bitmap课程中创建ImageData个对象:

Bitmap b = new Bitmap(filename);

使用此构造函数创建的Bitmap将从给定路径中的文件创建FileStream,并将FileStream保持打开状态,直到Bitmap被处置为止,如上所述在文档中:

  

文件保持锁定状态,直到处理了位图。

要解决此问题,您可以自行从文件中填充的Bitmap构建MemoryStream

byte[] data = File.ReadAllBytes(filename);
MemoryStream stream = new MemoryStream(data);
Bitmap b = new Bitmap(stream);

这样,Bitmap保持打开的流是您创建的MemoryStream,而不是保持文件锁定的FileStream