[英]C# WriteLine : The process cannot access the file because it is being used by another process
我有一个函数可以读取文件夹中的所有文件 .log 并提取每个错误行,然后将其写入 .csv 文件。 它适用于小日志文件,但不适用于 >600Ko 之类的“大文件”,并返回错误“该进程无法访问该文件,因为它正被另一个进程使用。”
我所有的日志文件都重新组合在“日志”文件夹中。
/*
* 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);
}
}
}
然后在主课上我做:
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);
}
因此,根据评论和我的理解,我尝试首先恢复所有日志并将其存储在一个列表中,然后从列表中将所有日志写入我的 conf.csv 文件中。
我想这不是最好的代码,但它现在可以工作,即使有大文件我也没有错误。
/*
* 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);
}
}
获取使用此方法锁定文件的进程:
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;
}
然后杀死它:
List<Process> ps = WhoIsLocking("file path");
foreach(Process p in ps)
p.Kill();
完毕;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.