file lock on write and read - c#

I have an xml file that has different marks in it that i need to update and need to pick up. this mark is from an api and is used so i only get new data. however when i try to write away the data or read the file it get locks all the time. these are the 2 functions that i use to write or read from the file.
private void SetMark(string name, string mark)
{
var marksfile = (string)_appSettings.GetValue("MarksFile", typeof(string));
_marks = new dsMarks();
try
{
if (File.Exists(marksfile))
{
using (var reader = new StreamReader(marksfile))
{
_marks.ReadXml(reader);
}
}
}
catch (Exception)
{
_marks = null;
throw;
}
var row = _marks.Mark.FindByName(name);
row.TimeMark = mark;
_marks.AcceptChanges();
using (var writer = new StreamWriter(marksfile))
{
_marks.WriteXml(writer);
}
}
private string GetMark(string name)
{
var marksfile = (string)_appSettings.GetValue("MarksFile", typeof(string));
_marks = new dsMarks();
try
{
if (File.Exists(marksfile))
{
using (var reader = new StreamReader(marksfile))
{
_marks.ReadXml(reader);
}
}
}
catch (Exception)
{
_marks = null;
throw;
}
var row = _marks.Mark.FindByName(name);
var mark = row.TimeMark;
return mark;
}

You might want to use FileStream instead of StreamReader as the former locks the file from other accessors. FileStream is better for read sharing.
private string GetTrimbleMark(string name)
{
var marksfile = (string)_appSettings.GetValue("MarksFile", typeof(string));
_marks = new dsMarks();
try
{
if (File.Exists(marksfile))
{
using (var reader = new FileStream(marksfile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
_marks.ReadXml(reader);
}
}
}
catch (Exception)
{
_marks = null;
throw;
}
var row = _marks.Mark.FindByName(name);
var mark = row.TimeMark;
return mark;
}

I 'll add fileAccess before openning my streamreader
if (File.Exists(marksfile))
{
FileStream fs = new FileStream(marksfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (var reader = new StreamReader(fs))
{
_marks.ReadXml(reader);
}
}

Related

How do I display mysql data in csv file after I sucessfully read the data in c#

Below is my Connectionstring and sucessfully read the data. It will return total rows of my data.
private static async Task<List<OperatorErrorTransaction>> GetDevIndex()
{
try
{
var currentConnectionDev = new CurrentConnection(Configuration["ConnectionStrings:Default"], currentRequest);
Console.WriteLine("\nPress the Enter key to exit the application...\n");
var response = await currentConnectionDev.DbConnection.QuerySafeAsync<OperatorErrorTransaction>(GenerateGetDatabaseIndexQuery());
return response.ToList();
}
catch (Exception ex)
{
return new List<OperatorErrorTransaction>();
}
}
private static string GenerateGetDatabaseIndexQuery()
{
return #"SELECT * FROM test.operator_error_transaction";
}
Below is the csv CreateFile function. Right now i looking a way how to implement mysql data into the csv file.
public static void CreateFile(List<OperatorErrorTransaction> result)
{
string myFileName = String.Format("{0:yyyy-MM-dd-HHmm}{1}", DateTime.Now, ".csv");
string myFullPath = Path.Combine("D:\\", myFileName);
using (var mem = new MemoryStream())
using (StreamWriter writer = File.CreateText(myFullPath))
using (var csvWriter = new CsvWriter(writer))
{
csvWriter.Configuration.Delimiter = ";";
csvWriter.WriteField(result);
csvWriter.NextRecord();
writer.Flush();
var result1 = Encoding.UTF8.GetString(mem.ToArray());
Console.WriteLine(result1);
}
}
I have created a class for the variables as well such as public string BetId { get; set; } etc...

How to Suppy Data Model to Print Function

I have a Print function which calls by different forms in my Project. Previously I was using DataSet as on my parameter, Now I switched to Data model. I am not sure how to retrieve information from different data model each time. Here is my old code.
public static void Print(string templeteID, DataSet dsSource,bool bPreview)
{
try
{
TPX.HMI.BusinessLogic.SystemSetting.ReportTemplate bll = new TPX.HMI.BusinessLogic.SystemSetting.ReportTemplate();
DataSet dsTemp = bll.RetrieveReportTemplateByID(templeteID);
if (dsTemp.Tables[0].Rows.Count > 0)
{
FileStream fs = new FileStream(Application.StartupPath + #"\\temp.repx", FileMode.Create);
Byte[] aryFile = dsTemp.Tables[0].Rows[0]["TemplateFile"] as Byte[];
fs.Write(aryFile, 0, aryFile.Length);
fs.Close();
}
string reportPatch = Application.StartupPath + #"\\temp.repx";
//开始打印
if (!System.IO.File.Exists(reportPatch))
{
MessageBox.Show(TPX.LanguageHelper.GetSystemKeyValue(GlobalParameters.Language, "TPX_TF_HMI_Print_TemplateError"));
return;
}
System.IO.FileStream stream = new System.IO.FileStream(reportPatch, System.IO.FileMode.Open);
XtraReport mReport = DevExpress.XtraReports.UI.XtraReport.FromStream(stream, true);
stream.Close();
if (dsSource != null) //传入数据集
{
mReport.DataSource = dsSource;
mReport.DataMember = dsSource.Tables[dsSource.Tables.Count - 1].TableName;
}
mReport.Name = "TPX";
mReport.RequestParameters = false;
mReport.PrintingSystem.ShowPrintStatusDialog = false;
mReport.PrintingSystem.ShowMarginsWarning = false;
if (!string.IsNullOrEmpty(GlobalParameters.DefaultPrinter))
mReport.PrintingSystem.PageSettings.PrinterName = GlobalParameters.DefaultPrinter;
mReport.CreateDocument();
if (bPreview)
mReport.ShowPreviewDialog();
else
mReport.Print();
}
catch (Exception ex)
{
MessageBox.Show((TPX.LanguageHelper.GetSystemKeyValue(GlobalParameters.Language, "TPX_TF_HMI_Print_TemplatePrintEx")) + ex.Message);
}
}

File used by another process ; PDF.JS ; iText

I'm using PDF.JS to display document that I upload to the server in canvas element using PDF.JS that's working perfectely. That time i'm using iTextSharp to digitally sign the document. When i try to sign the document an Exception is throwed (Exception.IO.Exception) The file is already used by another process. here is my Code for uploding the file :)
[HttpPost]
public async Task<JsonResult> Upload()
{
string fileName = null;
try
{
foreach (string item in Request.Files)
{
var fileContent = Request.Files[item];
if(fileContent != null && fileContent.ContentLength > 0)
{
var inputStream = fileContent.InputStream;
fileName = fileContent.FileName;
string path = Path.Combine(Server.MapPath("~/UploadFolder"), fileName);
using (fileContent.InputStream)
{
using (var stream = new FileStream(path, FileMode.Create))
{
await inputStream.CopyToAsync(stream);
}
}
}
}
}
catch (Exception e)
{
return Json("Upload failed");
}
return Json(fileName);
}
There's how i display PDF in canvas
$(document).ready(function () {
$("#btn2").click(function () {
var url = document.getElementById("document-to-sign").getAttribute("required-document");
if (url != "" && url != null) {
var pdfDoc = null,
pageNum = 1,
pageRendering = false,
pageNumPending = null,
scale = 1.5,
canvas = document.getElementById('document-to-sign'),
ctx = canvas.getContext('2d');
function renderPage(num) {
pageRendering = true;
pdfDoc.getPage(num).then(function (page) {
var viewport = page.getViewport(scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
pageRendering = false;
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
document.getElementById('page_num').textContent = pageNum;
}
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
function onPrevPage() {
if (pageNum <= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById('prev').addEventListener('click', onPrevPage);
function onNextPage() {
if (pageNum >= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
}
document.getElementById('next').addEventListener('click', onNextPage);
PDFJS.getDocument(url).then(function (pdfDoc_) {
pdfDoc = pdfDoc_;
document.getElementById('page_count').textContent = pdfDoc.numPages;
renderPage(pageNum);
});
PDFJS.disableStream = true;
$("#document-to-sign").removeAttr("required-document");
}
});
I finally that's how i'm signing the document (Adding the empty field to sign)
public static void AddField(string src,
Double x1X, Double x1Y, Double x2X, Double x2Y, int page,
string User)
{
try
{
PdfReader reader = new PdfReader(src);
using (PdfStamper s = new PdfStamper(reader, new FileStream(src, FileMode.Open)))
{
PdfFormField field = PdfFormField.CreateSignature(s.Writer);
field.FieldName = "Signature de " + User;
field.SetWidget(new Rectangle(Convert.ToSingle(x1X), Convert.ToSingle(x1Y), Convert.ToSingle(x2X), Convert.ToSingle(x2Y)), PdfAnnotation.HIGHLIGHT_PUSH);
field.Flags = PdfAnnotation.FLAGS_PRINT;
s.AddAnnotation(field, page);
}
}
catch (Exception e)
{
logger.Fatal(e.ToString());
throw e;
}
}
I'm stacked in this line
using (PdfStamper s = new PdfStamper(reader, new FileStream(src, FileMode.Open)))
EDIT:
I'm just adding the siging field in this step. Signing the document will be the next task, in console application i'm singing the document with a self-certificate.
Upload the document, and adding the signing field and signing it will be further :)
Sorry for the confussion.
Thanks a lot. :)
I just found what i'm missing in reading the file
refer to this
Cannot access the file because it is being used by another process
i was passing the url of the file instead of reading the all bytes from stream
PdfReader reader = new PdfReader(src);
PdfReader reader = new PdfReader(System.IO.File.ReadAllBytes(filePath))

How to serialize and deserialize data in/from XML File using c#?

I'm using winforms and c# to save data in xml file. I successfully insert my data into the xml file and display it in my winform but the problem is when i close and open again the form to save again another data the system display this message:
"The process can't access to the file "xmlfile path" because it's
being in use by another process"
I´m using the code below:
class information.cs:
private string id_x;
private string id_y;
private string fname_x;
private string fname_y;
public string ID_X
{
get { return id_x; }
set { id_x = value; }
}
public string ID_Y
{
get { return id_y; }
set { id_y = value; }
}
public string Fname_X
{
get { return fname_x; }
set { fname_x = value; }
}
public string Fname_Y
{
get { return fname_y; }
set { fname_y = value; }
}
Class saveXML.cs:
public static void SaveData(object obj, string filename)
{
XmlSerializer sr = new XmlSerializer(obj.GetType());
TextWriter writer = new StreamWriter(filename);
sr.Serialize(writer,obj);
writer.Close();
}
in the load form:
if (File.Exists("Patient_Data.xml"))
{
XmlSerializer xs = new XmlSerializer(typeof(Information));
FileStream read = new FileStream("Patient_Data.xml", FileMode.Open, FileAccess.Read);
Information info = (Information)xs.Deserialize(read);
int x1 = Int32.Parse(info.ID_X);
int y1 = Int32.Parse(info.ID_Y);
int x2 = Int32.Parse(info.Fname_X);
int y2 = Int32.Parse(info.Fname_Y);
this.tlp_id.Location = new Point(x1, y1);
this.tlp_fname.Location = new Point(x2, y2);
Your are not closing the FileStream after you have read all information from it.
FileStream read = new FileStream("Patient_Data.xml", FileMode.Open, FileAccess.Read);
Information info = (Information)xs.Deserialize(read);
read.Close();
A better way to ensure that also in case of an exception the FileStream is closed, is to use a using-statement.
using(FileStream read = new FileStream("Patient_Data.xml", FileMode.Open, FileAccess.Read)) {
Information info = (Information)xs.Deserialize(read);
}

Load a xml file using XDocument.Load from FileSystemWatcher. Error "The process cannot access the file..etc"

Is there a way to fix the error "The process cannot access the file..etc". The flow is that the filesystemwatcher will watch for a xml file when I detects a xml file i need to read a specific node from the xml file.
How can I fix this? Any ideas or suggestions will be a big help. Thanks
Here is the filesystemwatcher code
private void fileSystemWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
try
{
string type = GetType(e.FullPath).ToUpper();
if (type == "CC")
{
if (Global.pc_flag)
{
ProcessPC(e.FullPath);
}
else if (Global.mw_flag)
{
ProcessMW(e.FullPath);
}
else
{
ProcessXML(e.FullPath);
}
}
else if (type == "GC")
{
ProcessMW(e.FullPath);
}
//Process(e.FullPath);
}
catch(Exception ex)
{
error++;
lblErrors.Text = error.ToString();
MessageBox.Show(ex.Message);
}
}
Here what contains of GetType
private string GetType(string file)
{
string type = string.Empty;
using (var stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var request = XDocument.Load(stream);
var get_command = from r in request.Descendants("Transaction")
select new
{
Type = r.Element("Type").Value
};
foreach (var c in get_command)
{
type = c.Type;
}
}
return type;
}
You don't use your stream in code and while the stream is open you can not access the file in XDocument.Load(file)
private string GetType(string file)
{
string type = string.Empty;
var request = XDocument.Load(file);
var get_command = from r in request.Descendants("Transaction")
select new
{
Type = r.Element("Type").Value
};
foreach (var c in get_command)
{
type = c.Type;
}
return type;
}

Categories