0

I've a folder named testPhotos with some images. Based on the image creation date, I want to create a new folder by image creation year and then move the image to that folder.

For example, testPhotos has image named 01.jpg which was created on 2011. So I want to create a folder named 2011 inside testPhotos like testPhotos\2011 and move image to that folder. While doing this I am getting The process cannot access the file because it is being used by another process. error while moving image from one folder to another.

Code:

private void button1_Click(object sender, EventArgs e)
{
    var creationDate = new DateTime();
    var dateList = new List<String>();
    var fileName = String.Empty;
    var sourceFolder = @"C:\My Stuff\Test Porjects\testPhotos";

    String[] images = Directory.GetFiles(sourceFolder);

    if (images.Count() > 0)
    {
        foreach (var imagePath in images)
        {
            fileName = Path.GetFileName(imagePath);
            creationDate = GetDateTakenFromImage(imagePath);
            var date = creationDate.GetDateTimeFormats()[5].Replace("-", "/");

            if (!String.IsNullOrEmpty(date))
            {
                var year = date.Substring(0, 4);
                var destinationFolder = sourceFolder + "\\" + year;

                if (!Directory.Exists(destinationFolder))
                {
                    Directory.CreateDirectory(destinationFolder);

                    String fileToMove = sourceFolder+ "\\" + fileName;
                    String moveTo = destinationFolder + "\\" + fileName;

                    File.Move(fileToMove, moveTo);

                }
            }
        }
    }
}

private DateTime GetDateTakenFromImage(string path)
{
    Image myImage = Image.FromFile(path);
    PropertyItem propItem = myImage.GetPropertyItem(36867);
    string dateTaken = new Regex(":").Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
    return DateTime.Parse(dateTaken);
}

Screenshot of error

Any ideas?

GThree
  • 2,708
  • 7
  • 34
  • 67
  • 2
    I would guess you that you have a preview of that image or something else open, that already accesses the file. – Michael Sander Aug 12 '15 at 21:18
  • Are you using `Image.FromFile()`?... – Idle_Mind Aug 12 '15 at 21:43
  • Bit of code review: using the `Path.Combine` method is safer (more refactor-friendly; less error prone) than string concatenation when building file paths: `String filePath = Path.Combine(sourceFolder, fileName);` – Sam Axe Aug 12 '15 at 22:41
  • @MichaelSander I also assumed that but I am sure the image is neither open nor accessed by anything else. – GThree Aug 13 '15 at 13:02
  • @RobinHood if you accessed this file before, e.g. with streams, make sure to call `Dispose()`. Otherwise the file might still be locked until the garbage collector hooks in. Maybe you can share also some other code accessing this file? This would help identifieing the problem. – Michael Sander Aug 13 '15 at 13:04
  • @MichaelSander Please see my updated code. I've posted my full code. – GThree Aug 13 '15 at 13:12

1 Answers1

2

This looks like a missing dispose on the image, try with the following:

private DateTime GetDateTakenFromImage(string path)
{
    using (Image myImage = Image.FromFile(path))
    {
        PropertyItem propItem = myImage.GetPropertyItem(36867);
        string dateTaken = new Regex(":").Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
        return DateTime.Parse(dateTaken);
    }
}
Michael Sander
  • 2,677
  • 23
  • 29
  • It works now. I am surprised I missed that but lesson learnt. Thank you – GThree Aug 13 '15 at 13:25
  • Quick question: How can I get only images from the folder? I tired `String[] images = Directory.GetFiles(sourceFolder, "*.png" + "*.jpg" + "*.jpeg" + "*.jfif" + "*.bmp" + "*.tif" + "*.tiff" + "*.gif");` and `String[] images = Directory.GetFiles(sourceFolder, "*.png; *.jpg; *.jpeg; *.jfif; *.bmp;*.tif; *.tiff; *.gif");` but it returns nothing – GThree Aug 13 '15 at 13:43
  • [see this](http://stackoverflow.com/questions/7039580/multiple-file-extensions-searchpattern-for-system-io-directory-getfiles) – Michael Sander Aug 13 '15 at 13:45