我有一个程序可以扫描目录中的文本文件,遍历每一行并根据每行中的前缀进行解析。该程序充当提取器,从前缀“Hxx”上的Base64字符串中提取tif图像。当程序从“Hxx”行获取图像时,它只是删除原始文件。
我想要做的是保持行“TXA”的过滤条件,但不是将“Hxx”行上的字符串转换为图像并删除文件,我想保留文件的全部内容。基本上,只使用程序根据行“TXA”的条件来解析和过滤文本文件。
我知道在我的case
循环的foreach
“TXA”中,我需要将整个文件保存到内存流中,以便在程序结束时重新写入文件。我现在还不确定。
非常感谢任何帮助。
/// <summary>
/// This method will open, read and parse out the image file and save it to disk.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
static bool ParseHFPFile(string inputFileName, string outputFileName)
{
List<MemoryStream> tiffStreamList = new List<MemoryStream>();
// 1. grab file contents.
string fileContents = ProgramHelper.GetFileContents(inputFileName);
if (string.IsNullOrEmpty(fileContents))
{
return false; // errors already raised.
}
Log("[O] ", false);
// 2. split file contents into a string array.
string[] fileContentStringList = fileContents.Split('\r');
if (fileContentStringList.Length == 0)
{
Log(" ERROR: Unable to split file contents on [CR] character.");
return false;
}
// 3. loop through the file lines and parse each "section" based on it's prefix.
string mrn = string.Empty;
string dos = string.Empty;
string imgType = string.Empty;
foreach (string line in fileContentStringList)
{
if (string.IsNullOrEmpty(line))
{
continue;
}
string prefix = line.Substring(0, 3);
switch (prefix)
{
case "MSH":
break;
case "EVN":
break;
case "PID":
mrn = line.Split('|')[3].Split('^')[0];
break;
case "PV1":
dos = line.Split('|')[44];
if (!String.IsNullOrWhiteSpace(dos))
{
dos = dos.Substring(0, 8);
}
break;
case "TXA":
imgType = line.Split('|')[2].Split('^')[0];
if (imgType == "EDH02" || imgType == "EDORDH")
{
Log("[NP]");
return true;
}
break;
case "OBX":
break;
case "Hxx":
// 0 - Hxx
// 1 - page number
// 2 - image type
// 3 - base64 encoded image.
// 1. split the line sections apart based on the pipe character ("|").
string[] hxxSections = line.Split('|');
byte[] decodedImageBytes = Convert.FromBase64String(hxxSections[3].Replace(@"\.br\", ""));
// 2. create a memory stream to store the byte array.
var ms = new MemoryStream();
ms.Write(decodedImageBytes, 0, decodedImageBytes.Length);
// 3. add the memory stream to a memory stream array for later use in saving.
tiffStreamList.Add(ms);
break;
case "Z":
break;
}
}
Log("[P] ", false);
// 4. write the memory streams to a new file.
ImageCodecInfo icInfo = ImageCodecInfo.GetImageEncoders().Single(c => c.MimeType == "image/tiff");
System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.SaveFlag;
var ep = new EncoderParameters(1);
// 5. create references to the EncoderValues we will use
var ep1 = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
var ep2 = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
var ep3 = new EncoderParameter(enc, (long)EncoderValue.Flush);
string newOutputFilePath = Path.GetDirectoryName(outputFileName) + @"\";
string newOutputFileName = newOutputFilePath + mrn + "_" + dos + ".dat";
bool success = false;
int suffix = 1;
while (!success)
{
if (File.Exists(newOutputFileName))
{
newOutputFileName = newOutputFilePath + mrn + "_" + dos + "_" + suffix + ".dat";
}
else
{
success = true;
}
suffix++;
}
Log(string.Format("[NewFile: {0}] ", Path.GetFileName(newOutputFileName)), false);
var strm = new FileStream(newOutputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
System.Drawing.Image pages = null;
int frame = 0;
int pageCount = tiffStreamList.Count;
Log("[WT:", false);
try
{
foreach (MemoryStream m in tiffStreamList)
{
if (frame == 0)
{
ep.Param[0] = ep1;
pages = Image.FromStream(m, false, false);
pages.Save(strm, icInfo, ep);
}
else
{
ep.Param[0] = ep2;
if (pages != null)
pages.SaveAdd(Image.FromStream(m, false, false), ep);
}
if (frame == pageCount - 1)
{
ep.Param[0] = ep3;
if (pages != null)
pages.SaveAdd(ep);
}
frame++;
Log(".", false);
//m.Close();
m.Dispose();
}
Log("]");
return true;
}
catch (Exception ex)
{
Log(" EXCEPTION: " + ex.Message + Environment.NewLine + ex.StackTrace);
return false;
}
finally
{
}
}
答案 0 :(得分:1)
我很高兴您成功完成了任务。如果我的评论帮助您解决了问题,我会将其作为答案发布,以便您可以接受它。
因此,您可以直接创建两个List<string>
,而不是寻找更复杂的方法:
List<string> TXA = new List<string>();
List<string> FilesForDelete = new List<string>();
然后在您的代码中,取决于您要对文件执行的操作:
if (fileIsTXA)
{
TXA.Add(fileName);
}
else
{
FilesForDelete.Add(fileName);
}
稍后您可以使用这两个列表来提取文件名,并随意使用它们。