[英]fastest or most efficient way to process large number of image files in c#
我必須閱讀並找出存儲在我們網絡中的大約450,000個圖像文件的壓縮類型。 這是我到目前為止所能得到的,並且可以按需要工作,但是我觀察到的是每小時處理2000個文件。 速度較慢的原因之一可能是因為文件是從共享的網絡位置讀取的,但目前尚無解決方法。
任何建議將不勝感激。
using System;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Data;
using System.IO;
using FileHelpers;
using System.Threading.Tasks;
namespace CompressionTypeOfEDMSTiffs
{
public static class ImageProcessor
{
private static readonly object lockObject = new object();
public static void Process()
{
string docNumber = "";
try
{
Stopwatch _stopwatch = new Stopwatch();
_stopwatch.Start();
var filename = ConfigurationManager.AppSettings["filePath"].Trim();
var dtCsv = CsvEngine.CsvToDataTable(filename, ',');
dtCsv.Columns.Add("CompressionType");
dtCsv.Columns["CompressionType"].SetOrdinal(dtCsv.Columns.Count - 1);
//One-by one
//for (var rowNum = 0; rowNum < dtCsv.Rows.Count; rowNum++)
//{
// var imgPath = dtCsv.Rows[rowNum]["Path"].ToString();
// if (!string.IsNullOrWhiteSpace(imgPath) && imgPath.LastIndexOf(".") != -1)
// {
// if (imgPath.Substring(imgPath.LastIndexOf(".")).ToUpper().Equals(".TIF"))
// {
// docNumber = dtCsv.Rows[rowNum]["DOCNUMBER"].ToString();
// var compression = GetCompressionTypeFromImage(imgPath);
// dtCsv.Rows[rowNum]["CompressionType"] = compression;
// //if (Enum.IsDefined(typeof(CompressionTypes), compression))
// // dtCsv.Rows[rowNum]["CompressionType"] = compression.ToString();
// //else
// //{
// // dtCsv.Rows[rowNum]["CompressionType"] = "UnRecognised";
// //}
// Console.WriteLine(string.Format("Counter = {0}, docnumber = {1} , path = {2}, CT = {3}", rowNum, docNumber, imgPath, compression));
// }
// }
//}
//Multi-tasking
Parallel.ForEach(dtCsv.AsEnumerable(), drow =>
{
var imgPath = drow["Path"].ToString();
if (!string.IsNullOrWhiteSpace(imgPath) && imgPath.LastIndexOf(".") != -1)
{
if (imgPath.Substring(imgPath.LastIndexOf(".")).ToUpper().Equals(".TIF"))
{
docNumber = drow["DOCNUMBER"].ToString();
var compression = GetCompressionTypeFromImage(imgPath);
drow["CompressionType"] = compression;
Console.WriteLine(string.Format("docnumber = {0} , path = {1}, CT = {2}", docNumber, imgPath, compression));
}
}
});
if (File.Exists(filename))
File.Delete(filename);
//write CSV
var tempTable = dtCsv.Copy();
var headerRow = tempTable.NewRow();
foreach (DataColumn col in dtCsv.Columns)
headerRow[col.ColumnName] = col.ColumnName;
headerRow[headerRow.ItemArray.Length - 1] = "CompressionType";
tempTable.Rows.InsertAt(headerRow, 0);
CsvEngine.DataTableToCsv(tempTable, ConfigurationManager.AppSettings["filePath"].Trim());
_stopwatch.Stop();
Console.WriteLine(string.Format("Time elapsed in the process {0} minutes", _stopwatch.Elapsed.TotalMinutes.ToString("#.##")));
Console.ReadLine();
}
catch (Exception exception)
{
Console.WriteLine(!string.IsNullOrWhiteSpace(docNumber)
? string.Format("Error in document No {0} and the error is {1} stack trace {2}",
docNumber, exception.Message, exception.StackTrace)
: string.Format("Error is {0} stack trace {1}", exception.Message,
exception.StackTrace));
Console.ReadLine();
}
}
private static string GetCompressionTypeFromImage(string path)
{
string compression = "";
try
{
lock (lockObject)
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
using (Image sourceImage = Image.FromStream(fs))
{
var compressionTagIndex = Array.IndexOf(sourceImage.PropertyIdList, 0x103);
PropertyItem compressionTag = sourceImage.PropertyItems[compressionTagIndex];
var compressionType = (CompressionTypes)Enum.Parse(typeof(CompressionTypes),
BitConverter.ToInt16(compressionTag.Value, 0).ToString(CultureInfo.InvariantCulture));
if (Enum.IsDefined(typeof(CompressionTypes), compressionType))
compression = compressionType.ToString();
else
{
compression = "UnRecognised";
}
}
}
}
}
catch (Exception exFileStream)
{
compression = exFileStream.Message;
}
return compression;
//using (var sourceImage = Image.FromFile(path))
//{
// var compressionTagIndex = Array.IndexOf(sourceImage.PropertyIdList, 0x103);
// PropertyItem compressionTag = sourceImage.PropertyItems[compressionTagIndex];
// return (CompressionTypes)Enum.Parse(typeof(CompressionTypes), BitConverter.ToInt16(compressionTag.Value, 0).ToString(CultureInfo.InvariantCulture));
//}
}
}
public enum CompressionTypes
{
NoCompression = 1,
CcittGroup3 = 2,
FacsimilecompatibleCcittGroup3 = 3,
CcittGroup4 = 4,
Lzw = 5,
UnRecognised = 6,
ExceptionInFilehandling = 7
}
}
您可以在承載文件的服務器上運行程序,而不是通過網絡讀取文件嗎?
如果沒有,我將有一個程序將文件從網絡復制到本地文件夾以充當隊列。 然后讓第二個程序從本地隊列文件夾中讀取圖像,確定壓縮率,然后刪除該文件。 這樣可以將網絡IO時間與文件處理時間分開。
這些是我想到的幾件事:
Parallel.For
而不是for
瀏覽列表。 您不是在描述問題或問題。 在這個社區中這是不可接受的。 嘗試編輯您的問題,並更精確地解決您的問題以及您想做什么。
如果瓶頸是CPU,請嘗試一次在多個線程中進行工作。
如果瓶頸是文件訪問,則可以將圖像移動到SSD驅動器或內存驅動器中,然后從那里訪問它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.