这是我的第一个C#脚本和总体上第一个基于非SQL的脚本,我为此感到非常自豪(如果没有这个社区的帮助,我不能很快做到这一点,谢谢!),但是我知道这将是各种各样的混乱。
该脚本循环访问单个目录中的所有文件,从文件名中删除特殊字符,然后将文件重命名为标准的用户友好名称。该脚本正在目录中寻找一组特定的文件。如果发现目录中没有该文件,则将其移至安全文件夹并重命名。如果是文件夹
我正在处理4个文件,这些文件的动态名称将包含数字和特殊字符。重命名过程分为两个步骤:
从名称中删除特殊字符和数字。例如:从“ EOY 12.21.2018-12.28.2018 PRF.xls”到“ EOYPRF.xls”
重命名文件以清楚地标记文件是什么。例如:从“ EOYPRF.xls”到“ EOY_CompanyName.xls”
可能是偶然将文件添加到此目录中,并且由于它们是工资单文件,所以它们是高度机密的,除非需要移动(除非它们是4个文件之一),否则不能移动。将它们复制到文件存储所在目录的子目录中,然后重命名它们。
我还试图说明我的脚本或进程是否中途混乱。该脚本是SSIS中运行的较大自动化过程的一部分,因此存在许多故障点。该脚本可能会失败,并将4个文件中的一个或全部留在目录中。如果是这种情况,我需要在用户添加要处理的新的,未更改的主文件之前将文件移出主目录。如果目录包含具有相同最终名称的文件(“ EOY_CompanyName.xls”),则它将无法正常工作。
我正在通过将三个方案放在目录中来测试脚本。
我要面对的问题是在极少数情况下,即目录中既有未更改的主文件又有最终的主文件,脚本会运行直到第一个未更改的文件,删除特殊字符,然后在最终重命名时失败步骤是因为文件已经存在同名文件(上述3点中的方案3)。然后它将继续运行脚本,并将一个主文件移动到意外的文件目录中,并由于某种原因停止处理其他文件。我真的需要经验丰富的人的帮助。
我已经尝试了很多事情,但是我认为这取决于文件的处理顺序。我有两个名为“ a.xls”和“ b.xls”的文件,它们是意外文件的占位符。它们是目录中的前两个文件,并且始终先被处理。目录中的第三个文件是上面未更改形式的名称的文件(“ EOY 12.21.2018-12.28.2018 PRF.xls”)。它被重命名并移动到意外的文件文件夹中,但实际上应该将其传递以将包含最终名称(“ EOY_CompanyName.xls”)的主文件移动到意外的文件夹中。我想确保脚本仅在运行时才处理新文件,所以我想将所有无法通过脚本移动的已处理文件移动到另一个目录。
public void Main()
{
///Define paths and vars
string fileDirectory_Source = Dts.Variables["User::PayrollSourceFilePath"].Value.ToString();
string fileDirectory_Dest = Dts.Variables["User::PayrollDestFilePath"].Value.ToString();
string errorText = Dts.Variables["User::errorText"].Value.ToString();
DirectoryInfo dirInfo_Source = new DirectoryInfo(fileDirectory_Source);
DirectoryInfo dirInfo_Dest = new DirectoryInfo(fileDirectory_Dest);
string finalFileName = "";
List<string> files = new List<string>(new string[]
{
fileDirectory_Source + "EOY_PRF.xls",
fileDirectory_Source + "EOY_SU.xls",
fileDirectory_Source + "FS_PRF.xls",
fileDirectory_Source + "FS_SU.xls"
});
Dictionary<string, string> fileNameChanges = new Dictionary<string, string>();
fileNameChanges.Add("EOYReportPRF.xls", "EOY_PRF.xls");
fileNameChanges.Add("PayrollEOY.xls", "EOY_SU.xls");
fileNameChanges.Add("PRFFundingStatement.xls", "FS_PRF.xls");
fileNameChanges.Add("SUFundingStatement.xls", "FS_SU.xls");
///Determine if all files present
int count = dirInfo_Source.GetFiles().Length;
int i = 0;
///Loop through directory to standardize file names
try
{
foreach (FileInfo fi in dirInfo_Source.EnumerateFiles())
{
string cleanFileName = Regex.Replace(Path.GetFileNameWithoutExtension(fi.Name), "[0-9]|[.,/ -]", "").TrimEnd() + fi.Extension;
File.Move(fileDirectory_Source + Path.GetFileName(fi.Name), fileDirectory_Source + cleanFileName);
///Move unexpectd files in source directory
if (!fileNameChanges.ContainsKey(cleanFileName))
{
errorText = errorText + "Unexpected File: " + cleanFileName.ToString() + " moved into the Unexpected File folder.\r\n";
File.Move(dirInfo_Source + cleanFileName, dirInfo_Source + "Unexpected Files\\" + Path.GetFileNameWithoutExtension(cleanFileName) + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + fi.Extension);
}
if (fileNameChanges.ContainsKey(cleanFileName))
{
///Final Friendly File Name from Dict
var friendlyName = fileNameChanges[cleanFileName];
///Handle errors produced by files that already exist
if (files.Contains(fileDirectory_Source + friendlyName))//File.Exists(fileDirectory_Source + friendlyName))
{
MessageBox.Show("File.Exists(dirInfo_Source + friendlyName)" + File.Exists(dirInfo_Source + friendlyName).ToString() + " cleanFileName " + cleanFileName);
errorText = errorText + "File already exists: " + friendlyName.ToString() + " moved into the Unexpected File folder.\r\n";
File.Move(dirInfo_Source + friendlyName, dirInfo_Source + "Unexpected Files\\" + Path.GetFileNameWithoutExtension(friendlyName) + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Path.GetExtension(friendlyName));
return;
}
///Rename files to friendly name
File.Move(dirInfo_Source + cleanFileName, dirInfo_Source + friendlyName);
finalFileName = friendlyName.ToString();
}
///Count valid PR files
if (files.Contains(dirInfo_Source + finalFileName))
{
i++;
}
}
///Pass number of files in source folder to SSIS
Dts.Variables["User::FilesInSourceDir"].Value = i;
}
catch (Exception ex)
{
errorText = errorText + ("\r\nError at Name Standardization step: " + ex.Message.ToString()) + $"Filename: {finalFileName}\r\n";
}
///Search for missing files and store paths
try
{
if (i != 4)
{
var errors = files.Where(x => !File.Exists(x)).Select(x => x);
if (errors.Any())
errorText = (errorText + $" Missing neccessary files in PR Shared drive. Currently {i} valid files in directory.\r\n\n" + "Files missing\r\n" + string.Join(Environment.NewLine, errors) + "\r\n");
}
}
catch (Exception ex)
{
errorText = errorText + ("Error at Finding Missing PR Files step: " + ex.Message.ToString()) + "\r\n\n";
throw;
}
///Loop through directory to move files to encrypted location
try
{
if (i == 4)
foreach (FileInfo fi in dirInfo_Source.EnumerateFiles())
{
fi.MoveTo(fileDirectory_Dest + Path.GetFileName(fi.FullName));
}
}
catch (Exception ex)
{
errorText = errorText + ("Error at Move Files to Encrypted Directory step: " + ex.Message.ToString()) + "\r\n";
}
Dts.TaskResult = (int)ScriptResults.Success;
Dts.Variables["User::errorText"].Value = errorText;
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
理想情况下,我希望先移动文件夹中的所有文件,然后再清理和重命名文件,这样我就不会收到错误或将记录提交到已经存在的数据库中。
如果您能做到这一点,请多谢您的宝贵时间,感谢您抽出宝贵的时间阅读本文。你是英雄。
答案 0 :(得分:2)
据我了解,如果要删除“ 4个短名称”中的任何一个,请先删除它们。我将在下面进行介绍,请注意,我没有运行代码。 希望我理解你正确
///Loop through directory to standardize file names
try
{
//Cleanup source folder
foreach (string fileShortName in files)
{
if (File.Exists(fileDirectory_Source + fileShortName))
{
//Time to move the file, its old
errorText = errorText + "Old File: " + fileShortName + " moved into the Old File folder.\r\n";
File.Move(dirInfo_Source + fileShortName, dirInfo_Source + "Old Files\\" + Path.GetFileNameWithoutExtension(fileShortName) + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Path.GetExtension(fileShortName));
}
}
foreach (FileInfo fi in dirInfo_Source.GetFiles())