I have a function that read all my files .log inside a folder and extract each error line and later write it in a .csv file. It work with small log files but not with "big file" like >600Ko and return me the error "The process cannot access the file because it is being used by another process."
All my log file a regrouped inside a "logs" folder.
/*
* Extract data from the log file and right it in a conf.csv file
*/
public void DataExtract(string path)
{
int index = 0;
int nextLine = 0;
int descriptionLine = 0;
string firstLine = "";
string secondLine = "";
string description = "";
try
{
if (!String.IsNullOrEmpty(path))
{
// Read each line of the file into a string array. Each element
// of the array is one line of the file.
string[] logs = System.IO.File.ReadAllLines(path);
string[] confFile = System.IO.File.ReadAllLines(this.confPath);
// read each line of the log file
foreach (string log in logs)
{
if (log.Contains("ERROR"))
{
nextLine = index 1;
descriptionLine = index 2;
firstLine = log;
secondLine = logs[nextLine];
string checkDescr = "";
int descNb = descriptionLine 1;
checkDescr = logs[descNb];
description = logs[descriptionLine];
if (!description.Contains("at"))
{
descriptionLine ;
description = logs[descriptionLine];
}
if (!confFile.Any(s => s.Contains(firstLine)) || !confFile.Any(s => s.Contains(secondLine)))
{
using (StreamWriter sw = File.AppendText(this.confPath))
{
sw.WriteLine(string.Format("{0},{1},{2}", firstLine, secondLine, description));
}
}
index ;
}
Console.WriteLine("Done");
}
}
catch (Exception e)
{
Console.WriteLine("Problem !");
Console.WriteLine(e.Message);
}
}
}
Then in the Main class i do :
string logPath = directoryPath "\\logs";
string[] logfiles = Directory.GetFiles(logPath, "*.log");
ErrorRecover errorRecover = new ErrorRecover();
// For each log file call the methode for extracting errors logs
foreach (var file in logfiles)
{
Console.WriteLine(file);
errorRecover.DataExtract(file);
}
CodePudding user response:
So according to comments and what I understand I tried to first recover all my logs and store it inside a list and then from the list I write all in my conf.csv file.
I guess it's not the best code ever but it work for now and I don't have the error even with big files.
/*
* Extract data from the log file and right it in a conf.csv file
*/
public void DataExtract(string path)
{
int index = 0;
int nextLine = 0;
int descriptionLine = 0;
string firstLine="";
string secondLine="";
string description="";
var logDatas = new List<string>(); // list who will contain all errors from all logs files
string completLog= "";
try
{
if (!String.IsNullOrEmpty(path))
{
// Read each line of the file into a string array. Each element
// of the array is one line of the file.
string[] logs = System.IO.File.ReadAllLines(path);
string[] confFile = System.IO.File.ReadAllLines(this.confPath);
// read each line of the log file
foreach (string log in logs)
{
if (log.Contains("ERROR"))
{
nextLine = index 1;
descriptionLine = index 2;
firstLine = log;
secondLine = logs[nextLine];
string checkDescr="";
int descNb = descriptionLine 1;
checkDescr = logs[descNb];
description = logs[descriptionLine];
if (!description.Contains(" at "))
{
descriptionLine ;
description = logs[descriptionLine];
}
completLog = firstLine "," secondLine "," description;
logDatas.Add(completLog);
}
index ;
}
// recover log from the list and write it inside the conn.csv file
// this logic permit to avoid some error like "The process cannot access the file because it is being used by another process"
foreach (string log in logDatas)
{
if (!confFile.Any(s => s.Contains(firstLine)) || !confFile.Any(s => s.Contains(secondLine)))
{
using (StreamWriter sw = File.AppendText(this.confPath))
{
sw.WriteLine(log);
}
}
}
Console.WriteLine("Done");
}
}
catch (Exception e)
{
Console.WriteLine("Problem inside DataExtract method from ErrorRecover");
Console.WriteLine(e.Message);
}
}
CodePudding user response:
Get processes who locking file with this method:
static public List<Process> WhoIsLocking(string path)
{
uint handle;
string key = Guid.NewGuid().ToString();
List<Process> processes = new List<Process>();
int res = RmStartSession(out handle, 0, key);
if (res != 0) throw new Exception("Could not begin restart session. Unable to determine file locker.");
try {
const int ERROR_MORE_DATA = 234;
uint pnProcInfoNeeded = 0,
pnProcInfo = 0,
lpdwRebootReasons = RmRebootReasonNone;
string[] resources = new string[] { path }; // Just checking on one resource.
res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
if (res != 0) throw new Exception("Could not register resource.");
res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
if (res == ERROR_MORE_DATA) {
// Create an array to store the process results
RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];
pnProcInfo = pnProcInfoNeeded;
res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
if (res == 0) {
processes = new List<Process>((int)pnProcInfo);
// Enumerate all of the results and add them to the
// list to be returned
for (int i = 0; i < pnProcInfo; i )
try {
processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
}
// catch the error -- in case the process is no longer running
catch (ArgumentException) { }
}
else throw new Exception("Could not list processes locking resource.");
}
else if (res != 0) throw new Exception("Could not list processes locking resource. Failed to get size of result.");
}
finally
{
RmEndSession(handle);
}
return processes;
}
then kill that:
List<Process> ps = WhoIsLocking("file path");
foreach(Process p in ps)
p.Kill();
Done;