File being used by another process after using File.AppendAllText() - c#

The process cannot access the file 'file path' because it is being used by another process.
i have found these 2 question
File being used by another process after using File.Create()
and
Does File.AppendAllText close the file after the operation
this is an API that i have and need to save every request that comes in and the result that goes out,
there might be more than one request that a give time
my code
public static void SaveTheRequestAndResponse(string type, SearchRequest searchRequest = null, dynamic result = null)
{
var FilePath = AppDomain.CurrentDomain.BaseDirectory + #"SearchRequest";
bool exists = Directory.Exists(FilePath);
if (!exists)
{
var stream = Directory.CreateDirectory(FilePath);
}
if (type == "request")
{
string Space = ", ";
StringBuilder request = new StringBuilder();
request.Append("Search Id : " + searchRequest.ID);
request.Append(Space + "Company Name : " + searchRequest.CompanyName);
request.Append(Space + "Country Code : " + searchRequest.CountryCode);
request.Append(Space + "Search Type : " + searchRequest.SeacrhType);
request.Append(Space + "Request Time : " + DateTime.Now + Environment.NewLine);
var DataToBeSave = request.ToString();
System.IO.File.AppendAllText(FilePath + #"\" + "FileNAme" + DateTime.Now.ToString("dd-MM-yyyy") + ".txt", DataToBeSave + Environment.NewLine);
}
else
{
string Space = ", ";
StringBuilder SearchResult = new StringBuilder();
SearchResult.Append("The result for Request" + Space);
SearchResult.Append("Search Id : " + searchRequest.ID + Space);
SearchResult.Append("States Code : " + result.StatusCode + Space);
SearchResult.Append("Result Time : " + DateTime.Now + Environment.NewLine);
var DataToBeSave = SearchResult.ToString();
System.IO.File.AppendAllText(FilePath + #"\" + "FileNAme" + DateTime.Now.ToString("dd-MM-yyyy") + ".txt", DataToBeSave + Environment.NewLine);
}
}
my understanding is that the File.AppendAllText will close after the Operation so why do i get the this error

my code is having an race condition, and this is because the API is being call by more than one user at each given time, even that
System.IO.File.AppendAllText(FilePath + #"\" + "FileNAme" + DateTime.Now.ToString("dd-MM-yyyy") + ".txt", DataToBeSave + Environment.NewLine);
will close after the Operation, it still need time do its work and only one connection can be open at each give time so the thread need to be lock and that can be done by
private static Object thisLock = new Object();
lock (thisLock)
{
System.IO.File.AppendAllText(FilePath + #"\" + "DandB" + DateTime.Now.ToString("dd-MM-yyyy") + ".txt", DataToBeSave + Environment.NewLine);
}
Thanks to Abydal

Related

New line in text file using C# [duplicate]

This question already has answers here:
IOException: The process cannot access the file 'file path' because it is being used by another process
(12 answers)
Closed 1 year ago.
I'm a student who just started learning C#,
I'm trying to create Sign-Up and Login functions using text files, and save details that the user inputs into the textfile, but when I run my function again it rewrites what is already there instead of starting a new line.
This is a bit of my code that is important
using System;
using System.IO;
namespace SDD_Assessment_2
{
class Program
{
static void Main(string[] args)
{
//Write();
//GetTime();
var privInfo = SignUp();
var FullName = Profile(privInfo);
Profile(privInfo);
//Test(FullName);
}
const string filename = "Workout.txt";
static string[] SignUp()
{
string[] privinfo = new string[4];
Console.Write("First Name: ");
privinfo[0] = Console.ReadLine();
Console.Write("Last Name: ");
privinfo[1] = Console.ReadLine();
Console.Write("Email: ");
privinfo[2] = Console.ReadLine();
Console.Write("Password: ");
privinfo[3] = Console.ReadLine();
StreamWriter NewAccount = new StreamWriter(filename);
//NewAccount.WriteLine(privinfo[0] + "," + privinfo[1] + "," + privinfo[2] + "," + privinfo[3] + Environment.NewLine);
File.AppendAllText(filename, privinfo[0] + ", " + privinfo[1] + "," + privinfo[2] + "," + privinfo[3] + Environment.NewLine);
NewAccount.Close();
return privinfo;
}
}
}
When I run it right now, it says "System.IO.IOException: The process cannot access the file 'filename' because it is being used by another process."
Your code is mostly correct. You need to change
StreamWriter NewAccount = new StreamWriter(filename);
//NewAccount.WriteLine(privinfo[0] + "," + privinfo[1] + "," + privinfo[2] + "," + privinfo[3] + Environment.NewLine);
File.AppendAllText(filename, privinfo[0] + ", " + privinfo[1] + "," + privinfo[2] + "," + privinfo[3] + Environment.NewLine);
NewAccount.Close();
to just
File.AppendAllText(filename, privinfo[0] + ", " + privinfo[1] + "," + privinfo[2] + "," + privinfo[3] + Environment.NewLine);
Your allocation of NewAccount opens a stream to the file, which keeps the file handle open. That means your File.AppendAllText can't complete, because the file was previously opened in a non-sharing mode.
If you had deleted File.AppendAllText you wouldn't get the error, but you'd end up with a zero byte file as you wrote nothing to the stream.
As you are not using NewAccount at all, removing those lines will allow File.AppendAllText to complete without error, and... append all the text you expect, which would be the values for first and last names, email and password.
I try, it work
Don't open stream when you not used
File name include directory
class Program
{
static void Main(string[] args)
{
SignUp();
}
const string filename = "Workout.txt";
static string[] SignUp()
{
string[] privinfo = new string[4];
privinfo[0] = "First Name:";
privinfo[1] = "Last Name: ";
privinfo[2] = "Email: ";
privinfo[3] = "Password: ";
File.AppendAllText(Path.Combine(Environment.CurrentDirectory, filename), privinfo[0] + ", " + privinfo[1] + "," + privinfo[2] + "," + privinfo[3] + Environment.NewLine);
return privinfo;
}
}
Run 2 times
file content is
First Name:, Last Name: ,Email: ,Password:
First Name:, Last Name: ,Email: ,Password:

Delete file which cannot delete because is used by another process

I know you are going to tell me that this question is stupid but I really cannot find a solution to delete my file.
In fact, I open a connection to an .add file (same style as SQL in a way) but afterwards I cannot delete it because it is used by another process which is the process of my application.
While doing some research on the internet I was able to find the solution to kill the process however if I do this it stops my application. Then I also found the GC collect but it doesn't work : /
There is my code :
try
{
string idClient = "parfilux";
string tableName = "ACT,ACF";
string dataSourceDBF = "C:/winbooks/data/parfilux";
string path = dataSourceDBF ;
string pathTemp = dataSourceDBF + "/CopyTempWebService/";
if (!Directory.Exists(pathTemp)) Directory.CreateDirectory(pathTemp);
string addFile = path + "/" + idClient + ".add";
File.Copy(addFile, pathTemp + idClient.ToUpper() + ".add");
File.Copy(addFile.Replace(".add", ".ai"), pathTemp + "/" + idClient.ToUpper() + ".ai");
File.Copy(addFile.Replace(".add", ".am"), pathTemp + "/" + idClient.ToUpper() + ".am");
tableName = tableName.Replace(" ", "");
string[] tables = tableName.Split(',');
string pathTable = null;
foreach (string tab in tables)
{
pathTable = path + "/" + idClient.ToUpper() + "_" + tab.ToUpper() + ".dbf";
File.Copy(pathTable, pathTemp + idClient.ToUpper() + "_" + tab.ToUpper() + ".dbf");
File.Copy(pathTable.Replace(".dbf", ".cdx"), pathTemp + idClient.ToUpper() + "_" + tab.ToUpper() + ".cdx");
}
AdsConnection dbfCo;
//dbfCo.Close();
dbfCo = new AdsConnection(#"data Source=" + dataSourceDBF + "/CopyTempWebService/" + idClient + ".add;User ID=admin;Password=;ServerType=Local;ReadOnly=true;pooling=true;TrimTrailingSpaces=true;ShowDeleted=TRUE;TableType=CDX;LockMode=COMPATIBLE");
dbfCo.Open();
//QueryDataDBF(tableName, idClient, false);
dbfCo.Close();
dbfCo.Dispose();
//Process process = Process.GetCurrentProcess();
//Console.WriteLine(process.MainModule);
//process.Kill();
//foreach(Process pro in process)
//{
// Console.WriteLine(pro);
// if(pro.ProcessName == pathTemp + idClient.ToUpper() + ".add")
// {
// pro.Kill();
// }
//}
//System.GC.Collect();
//System.GC.WaitForPendingFinalizers();
//File.Delete(pathTemp + idClient.ToUpper() + ".add");
Directory.Delete(dataSourceDBF + "/CopyTempWebService", true);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
I open a connection to my .add with the Advantage Data Provider library.
Do you have any idea to fix this problem ? thank you in advance ;)

Log Exception Error on Network

I want to log Exception in case of error on network. I have made changes in global.asax file and generated log file in it. The code works fine on localhost but when I upload the dll of global.asax file on another server and change the web config according to network credentials similar to the localhost. In case of error the method doesnot seem to work nor the file is created to write the exception. Please help
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
try
{
DffUtility.AddCookie("verystart", "Very start of error");
Exception exc = Server.GetLastError();
Uri refurl = Request.UrlReferrer;
DffUtility.AddCookie("star655", "getting exception start");
string networkLogFolderPath = ConfigurationManager.AppSettings["Logpath"] + "\\" + DffUtility.WebSiteInfo.Folder + "\\" + DffUtility.WebSiteInfo.ThemeName + "\\";
DffUtility.AddCookie("path", networkLogFolderPath.ToString());
Network.connectToRemote(ConfigurationManager.AppSettings["Logpath"],
ConfigurationManager.AppSettings["networkusername"],
ConfigurationManager.AppSettings["pass"]);
string LogFolderPath = HttpContext.Current.Server.MapPath("~/ExceptionLogFiles/");
string filePath = networkLogFolderPath;
string stacktracemessage, stacktrace, Errormsg, extype, exurl;
stacktracemessage = (exc.InnerException).Message;
stacktrace = exc.ToString();
Errormsg = exc.GetType().Name.ToString();
extype = exc.GetType().ToString();
exurl = HttpContext.Current.Request.Url.ToString();
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(filePath)))
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(filePath));
if (DffUtility.Country > 0)
{
if (DffUtility.RegionArea > 0)
{
if (DffUtility.RegionCity > 0)
{
if (DffUtility.ProdID > 0)
{
filePath = (filePath + "Product_" + DffUtility.ProdID + "_" + DffUtility.RegionCity + "_" + DffUtility.RegionArea + "_" + DffUtility.Country + ".txt");
}
else
{
filePath = (filePath + "City_" + DffUtility.RegionCity + "_" + DffUtility.RegionArea + "_" + DffUtility.Country + ".txt");
}
}
else
{
filePath = (filePath + "Area_" + DffUtility.RegionArea + "_" + DffUtility.Country + ".txt");
}
}
else
{
filePath = (filePath + "Country_" + DffUtility.Country + ".txt");
DffUtility.AddCookie("start8", "After generating product file");
}
}
System.IO.File.Create(filePath).Dispose();
using (System.IO.StreamWriter sw = System.IO.File.AppendText(filePath))
{
string logFormat = Environment.NewLine + " " + Environment.NewLine;
DffUtility.AddCookie("start6", "in");
string error = "Error Message:" + " " + Errormsg + logFormat + "Exception Type:" + " " + extype + logFormat + " Error Page Url:" + " " + exurl + logFormat + " StackTraceMessage:" + " " + stacktracemessage + logFormat + " StackTrace:" + " " + stacktrace + logFormat + " " + refurl + logFormat;
sw.WriteLine("-----------Exception Details on " + " " + DateTime.Now.ToString() + "-----------------");
sw.WriteLine("-------------------------------------------------------------------------------------");
sw.WriteLine(error);
sw.WriteLine(logFormat);
sw.Flush();
sw.Close();
DffUtility.AddCookie("start4", " after getting generated log");
}
It's because your application runs under NETWORK SERVICE account (by default) and don't have permissions to write in ExceptionLogFiles folder. Add user Everyone in folder properties and grant him that permission

How can I check for a stream before initializing one in a loop in C#

I've got the following bit of code that generates a list I'm trying to process. I need to create multiple files as I go through the list.
Currently I'm getting the following error on the calls to genStream outside of the IF, (in and out of the FOREACH loop), and I'm not sure why:
The name genStream' does not exist in the current context
I'm trying to figure out how I can close the one stream, and open another in the IF statement. I tried to put a .close() before creating the new stream, and it gave me an error for using it before initializing the stream.
Here is my bit of code:
/// <summary>
/// Creates a file for each Genre, and writes movie info to each for the cooresponding movies
/// </summary>
/// <param name="cPath">Path to create HTML files in</param>
/// <param name="mList">List of Movies to generate Genre and Movie info from</param>
public static void WriteGenreHTML(string cPath, List<Movie> mList)
{
int lineID = 0;
string tmpGen = null;
string strHeader, strMovie, strGenre, tmpGenre = null;
// Gets a list of unique Genres from the MovieList
var distinctGenres = from m in mList
from genre in m.Genres
group genre by genre into genres
select genres.First();
// Gets a list of Movies with the associated Genres
var moviesWithGenre = from g in distinctGenres
from m in mList
where m.Genres.Contains(g)
orderby g, m.Title
select new { Genre = g, Movie = m };
// Traverses list of movies creating new HTML Genre files, and writing movie info to the HTML genre files
foreach (var m in moviesWithGenre)
{
// Creates new HTML file if new Genre is detected
if (m.Genre != tmpGen)
{
tmpGen = m.Genre;
// initiates streamwriter for catalog output file
FileStream fs = new FileStream(cPath + Path.DirectorySeparatorChar + m.Genre, FileMode.Create);
StreamWriter genStream = new StreamWriter(fs);
// Generates header info for new file, and new Genre
strHeader = "<style type=\"text/css\">\r\n" + "<!--\r\n" + "tr#odd {\r\n" + " background-color:#e2e2e2;\r\n" + " vertical-align:top;\r\n" + "}\r\n" + "\r\n" + "tr#even {\r\n" + " vertical-align:top;\r\n" + "}\r\n" + "div#title {\r\n" + " font-size:16px;\r\n" + " font-weight:bold;\r\n" + "}\r\n" + "\r\n" + "div#mpaa {\r\n" + " font-size:10px;\r\n" + "}\r\n" + "\r\n" + "div#genre {\r\n" + " font-size:12px;\r\n" + " font-style:italic;\r\n" + "}\r\n" + "\r\n" + "div#plot {\r\n" + " height: 63px;\r\n" + " font-size:12px;\r\n" + " overflow:hidden;\r\n" + "}\r\n" + "\r\n" + "div#genre_heading {\r\n" + " height: 50px;\r\n" + " font-size: 24px;\r\n" + " font-weight: bold;\r\n" + " text-align: center;\r\n" + " text-decoration: underline;\r\n" + "}\r\n" + "-->\r\n" + "</style>\r\n" + "\r\n" + "<html>\r\n" + " <body>\r\n" + " <table>\r\n";
strHeader += " <tr>\r\n" + " <td colspan=2>\r\n" + " <div id=\"genre_heading\">" + m.Genre + "</div>\r\n" + " </td>\r\n" + " </tr>\r\n" + "\r\n";
// Writes header HTML to stream
genStream.WriteLine(strHeader);
Console.WriteLine();
Console.WriteLine("Now Processing " + m.Genre);
}
// Generates the HTML for the Movie
strMovie = lineID == 0 ? " <tr id=\"odd\" style=\"page-break-inside:avoid\">\r\n" : " <tr id=\"even\" style=\"page-break-inside:avoid\">\r\n";
strMovie += " <td>\r\n" + " <img src=\".\\images\\" + m.Movie.ImageFile + "\" width=\"75\" height=\"110\">\r\n" + " </td>\r\n" + " <td>\r\n" + " <div id=\"title\">" + m.Movie.Title + "</div>\r\n" + " <div id=\"mpaa\">" + m.Movie.Certification + " " + m.Movie.MPAA + "</div>\r\n" + " <div id=\"genre\">" + strGenre + "</div>\r\n" + " <div id=\"plot\">" + m.Movie.Plot + "</div>\r\n" + " </td>\r\n" + " </tr>\r\n";
// Writes the HTML to the stream
genStream.WriteLine(strMovie);
lineID = lineID == 0 ? 1 : 0;
}
string closingHTML = " </table>\r\n" + " </body>\r\n" + "</html>";
genStream.WriteLine(closingHTML);
genStream.Close();
}
Side note. I'd GREATLY appreciate it if someone could point me towards something I can use to convert the HTML files into PDFs. I tried EO, and it has a nasty "watermark", and chokes on files over a couple MB (mine are 5-10mb+). I have WkHTMLToSharp, but I am not sure how to use it, and can't find any documentation on how to intitialize/use it.
Thanks as always!
Declare the genStream outside of foreach loop, and then initialize it as needed within the if statement:
StreamWriter genStream;
foreach (var m in moviesWithGenre)
{
// Creates new HTML file if new Genre is detected
if (m.Genre != tmpGen)
{
tmpGen = m.Genre;
// initiates streamwriter for catalog output file
FileStream fs = new FileStream(cPath + Path.DirectorySeparatorChar + m.Genre, FileMode.Create);
// Set genStream to the FileStream
genStream = new StreamWriter(fs);

Why is EO.PDF Timing Out When Converting HTML File to PDF in C#

I have the following bits of code:
public static void WriteHTML(string cFile, List<Movie> mList)
{
int lineID = 0;
string strMovie, strGenre, tmpGenre = null;
// initiates streamwriter for catalog output file
FileStream fs = new FileStream(cFile, FileMode.Create);
StreamWriter catalog = new StreamWriter(fs);
string strHeader = "<style type=\"text/css\">\r\n" + "<!--\r\n" + "tr#odd {\r\n" + " background-color:#e2e2e2;\r\n" + " vertical-align:top;\r\n" + "}\r\n" + "\r\n" + "tr#even {\r\n" + " vertical-align:top;\r\n" + "}\r\n" + "div#title {\r\n" + " font-size:16px;\r\n" + " font-weight:bold;\r\n" + "}\r\n" + "\r\n" + "div#mpaa {\r\n" + " font-size:10px;\r\n" + "}\r\n" + "\r\n" + "div#genre {\r\n" + " font-size:12px;\r\n" + " font-style:italic;\r\n" + "}\r\n" + "\r\n" + "div#plot {\r\n" + " height: 63px;\r\n" + " font-size:12px;\r\n" + " overflow:hidden;\r\n" + "}\r\n" + "-->\r\n" + "</style>\r\n" + "\r\n" + "<html>\r\n" + " <body>\r\n" + " <table>\r\n";
catalog.WriteLine(strHeader);
foreach (Movie m in mList)
{
strMovie = lineID == 0 ? " <tr id=\"odd\" style=\"page-break-inside:avoid\">" : " <tr id=\"even\" style=\"page-break-inside:avoid\">";
catalog.WriteLine(strMovie);
foreach (string genre in m.Genres)
tmpGenre += ", " + genre;
try
{ strGenre = tmpGenre.Substring(2); }
catch (Exception)
{ strGenre = null; }
strMovie = " <td>\r\n" + " <img src=\".\\images\\" + m.ImageFile + "\" width=\"75\" height=\"110\">\r\n" + " </td>\r\n" + " <td>\r\n" + " <div id=\"title\">" + m.Title + "</div>\r\n" + " <div id=\"mpaa\">" + m.Certification + " " + m.MPAA + "</div>\r\n" + " <div id=\"genre\">" + strGenre + "</div>\r\n" + " <div id=\"plot\">" + m.Plot + "</div>\r\n" + " </td>\r\n" + " </tr>\r\n";
catalog.WriteLine(strMovie);
lineID = lineID == 0 ? 1 : 0;
}
catalog.WriteLine(" </table>\r\n" + " </body>\r\n" + "</html>");
catalog.Close();
}
public static void WritePDF(string cFile, string pdfFile)
{
// Sets up PDF to write to
EO.Pdf.HtmlToPdf.Options.PageSize = new SizeF(8.5f, 11f);
EO.Pdf.HtmlToPdf.Options.OutputArea = new RectangleF(0.5f, .25f, 7.5f, 10.25f);
HtmlToPdf.ConvertUrl(cFile, pdfFile);
}
My HTML file writes fine, but when it tried to convert the HTML file to PDF I get an exception that it times out.
I did a test previously, and had it convert the code (not the file) within the WriteHTML function and it worked great. I have confirmed that the cFile exists and is a valid file (created previously in WriteHTML). The path to pdfFile is valid, and the documentation does not state the file needs to already exist (.ConvertHTML did not need an existing file).
Only thing I can think of is that the catalog.html file isn't released and ready to read yet. I made sure I closed it in the WriteHTML function. How can I test that the file is ready to be read?
Tried setting .MaxLoadWaitTime = 120000 with no luck.
Any clues would be greatly appreciated!
After a battery of further testing, and scouring the EO support forums, it appears to be a limitation of the free version of EO. It seems to have difficulty with HTML files over 3MB.
It's a shame since the EO product is very good, but not unfortunately not worth $250 IMO.

Categories

Resources