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);
}
Related
I am doing a project in C# using Winforms, and I want to create a Podcast RSS reader. So I have a XmlSerializer that saves a podcast entity to a podcastlist and I should then get a podcast.xml file in my project files that it then reads ( I guess). I got it to do exactly that, but with adding Categories. But when I want to read a URL that contains a RSS-file, it wont Save(Serialize) it using the XmlReader. Ive been staring at this for most of the day and I cant just figure out whats going wrong.
Here is my serializer and saved list of Podcasts.
protected string fileOfPodcasts = #"Podcasts.xml";
public List<Podcast> listOfPodcasts = new List<Podcast>();
public void SavePodcastList(List<Podcast> podcastList)
{
XmlSerializer xmlSerializer = new XmlSerializer(podcastList.GetType());
using (FileStream outFile = new FileStream(fileOfPodcasts, FileMode.Create,
FileAccess.Write))
{
xmlSerializer.Serialize(outFile, podcastList);
}
}
public List<Podcast> ReturnPodcasts()
{
List<Podcast> listOfPodcastsToBeReturned;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Podcast>));
using (FileStream inFile = new FileStream(fileOfPodcasts, FileMode.Open,
FileAccess.Read))
{
listOfPodcastsToBeReturned = (List<Podcast>)xmlSerializer.Deserialize(inFile);
}
return listOfPodcastsToBeReturned;
}
public void CreatePodcastObject ( string url, string interval, string category) // 3 parametrar
{
Podcast newPodcast = null;
{
newPodcast = new Podcast(url, interval, category);
}
podcastRepository.Create(newPodcast);
}
public void Create(Podcast entity)
{
podcastList.Add(entity);
SaveChanges();
}
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...
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);
}
}
I am using the elency solutions CSV library for C# to save and load some data from a file.
My code saves and loads correctly, but when I load and then try to save an error occurs, saying that another process is using the file.
The load method is this:
private void loadfile(string name)
{
int key = 696969;
CsvReader read = new CsvReader("data.csv");
try
{
do
{
read.ReadNextRecord();
} while (name != read.Fields[0]);
int decAgain = int.Parse(read.Fields[1], System.Globalization.NumberStyles.HexNumber); //convert to int
int dec = decAgain ^ key;
MessageBox.Show(dec.ToString());
}
catch (Exception)
{
MessageBox.Show("Not Found");
}
read = null;
}
As you can see, I am sort of disposing the "read" object.
Here is the save method:
private void savefile(string encrypted, string name)
{
CsvFile file = new CsvFile();
CsvRecord rec = new CsvRecord();
CsvWriter write = new CsvWriter();
rec.Fields.Add(name);
rec.Fields.Add(encrypted);
file.Records.Add(rec);
write.AppendCsv(file, "data.csv");
file = null;
rec = null;
write = null;
}
It always gets stuck on append csv.
I do understand the problem. The reader is not being closed successfully. How can I correctly close the file?
NB: I have tried read.Dispose() but it is not working.
Can you please help me out?
Regards
Use using to automatically dispose object. It may solve your issue.
private void savefile(string encrypted, string name)
{
using(CsvFile file = new CsvFile())
{
using(CsvRecord rec = new CsvRecord())
{
using(CsvWriter write = new CsvWriter())
{
rec.Fields.Add(name);
rec.Fields.Add(encrypted);
file.Records.Add(rec);
write.AppendCsv(file, "data.csv");
}
}
}
}
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;
}