我必须阅读并找出存储在我们网络中的大约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
}
}
答案 0 :(得分:3)
您可以在托管文件的服务器上运行程序,而不是通过网络读取文件吗?
如果没有,我会有一个程序从网络复制文件到本地文件夹作为队列。然后让第二个程序从本地队列文件夹中读取图像,确定压缩,然后删除该文件。这将网络IO时间与文件处理时间分开。
答案 1 :(得分:1)
这些是我想到的几件事:
Parallel.For
代替for
查看列表。答案 2 :(得分:0)
您没有描述问题或问题。这在社区中是不可接受的。尝试编辑您的问题,更准确地解决您的问题以及您想要做的事情。
如果您的瓶颈是您的CPU,请尝试一次在多个线程中完成工作。
如果您的瓶颈是文件访问权限,您可以将图像移动到SSD驱动器或内存驱动器中,然后从那里访问它们。