0

I have a fairly simple task - from a collection of images I need to extract the Creation Date, the Last Modified Date and the Picture Taken Date and write them to a text file. For the Picture Taken Date, I am using metadata-extractor.

This is some sample code,

    List<FileInfo> fileList = Utils.FileList(targetPath, true);
    foreach (FileInfo fi in fileList)
    {
        string dateTime = "";
        try
        {
            var metadatadir = ImageMetadataReader.ReadMetadata(fi.FullName);
            var subIfdDirectory = metadatadir.OfType<ExifSubIfdDirectory>().FirstOrDefault();
            dateTime = subIfdDirectory?.GetDescription(ExifDirectoryBase.TagDateTimeOriginal);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        DateTime creationDate = File.GetCreationTime(fi.FullName);
        DateTime modifiedDate = File.GetLastWriteTime(fi.FullName);
        string outputLine = "Filename " + fi.Name + "\t Creation Time: " + creationDate +
            "\t Modified Time: " + modifiedDate + "\t" + "Exif Time: " + dateTime + "\n";
        File.AppendAllText(targetFile, outputLine);
        fileCount++;
    }

I wrap a Stopwatch object around this block to measure performance and this is the result I get,

Processed 2244 files in 440218ms.

If I comment out the Exif code (the try-catch block) I get,

Processed 2244 files in 116928ms.

Am I using the library incorrectly? Is there a faster way of pulling the data out?

EDIT Based on feedback I have switched to using StreamWriter as below,

using (StreamWriter tFile = File.AppendText(targetFile))
{
    // Code
    tFile.WriteLine(outputLine);
}

Based on this latest change the time taken has been cut in half with the Exif code,

Processed 2244 files in 212278ms.

insomniac
  • 192
  • 1
  • 3
  • 16
  • Your code is identical to [this answer](https://stackoverflow.com/a/39839380/150605) (with the exception of `subIfdDirectory?.GetDescription()` vs. `subIfdDirectory?.GetDateTime()`) from someone claiming to be the author of that very library and touting its performance compared to `System.Drawing.Image`, so presumably that is the correct usage. It does provide an alternative method if you know the input format and can restrict the requested metadata. – Lance U. Matthews Apr 16 '20 at 21:46
  • The code is based off a sample on GitHub for this library, and that specifies using the `metadata-extractor` tag when posting on StackOverflow. Thanks for the link. – insomniac Apr 16 '20 at 21:53
  • Performance in your case is likely down to I/O. Now the code you're using pulls out all metadata types for all file formats. If you only want, day, Exif for JPEG files, itmay be possible to improve performance. – Drew Noakes Apr 17 '20 at 03:26
  • Instead of calling File.AppendAllText in the loop, create a stream writer and spend to that, so that you only open and close the output file once rather than once per input file. It will allow more buffering too. – Drew Noakes Apr 17 '20 at 03:28
  • I'm on my phone but can find you some code soon if you explain your use case in more detail. – Drew Noakes Apr 17 '20 at 03:29
  • Drew, thanks for the suggestion. Using `StreamWriter` has made a substantial improvement to the performance time. My use case is that I have a large library of files littered across many folders that have been backed up over the years from cameras, phones, etc. I want to organise them all by folders ordered by the exposure date. Any other optimisations you suggest? – insomniac Apr 17 '20 at 23:18

1 Answers1

0

Based on following comments from Drew Noakes,

Performance in your case is likely down to I/O. Now the code you're using pulls out all metadata types for all file formats. If you only want, day, Exif for JPEG files, itmay be possible to improve performance

Instead of calling File.AppendAllText in the loop, create a StreamWriter and spend to that, so that you only open and close the output file once rather than once per input file. It will allow more buffering too.

I have done exactly this and performance speed has doubled, which is good enough for my purposes. See edit in the original post.

insomniac
  • 192
  • 1
  • 3
  • 16