I am writing program events to a txt file as a log but the time stamps are not updating at each point. I have declared the following string:
string timeStamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ff");
string taskComplete = (timeStamp) + " Task Complete";
which i am calling at different points through the program:
using (StreamWriter w_Log = new StreamWriter(file_Log, true))
{
w_Log.WriteLine(taskComplete);
w_Log.Close();
}
There are several more strings declared using timeStamp though the program as well. Here is an example of the log file:
2014/02/22 10:07:26.71 Process started
2014/02/22 10:07:26.71 Task Complete
2014/02/22 10:07:26.71 Task Complete
2014/02/22 10:07:26.71 Process complete, time elapsed: 0.496 seconds
As you can see, the time seems to be static even though it has taken 49ms to complete. When the program is run again, the time has changed to the current time but the same issue, the time written is the same throughout.
Do I need to use a different method or am I using this one incorrectly?
So, at step 1 you're defining a string as being DateTime.Now with a particular format
At each point, you're just showing the same string. The string is fixed, it's not going to invoke DateTime.Now each time you run it.
So if you want it to change - you're going to need to call DateTime.Now each time.
w_Log.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ff") + " Task Complete ");
You are defining taskComplete as a string once and using it over and over again. It doesn't update regardless of how you define it. You could set it once now and leave your the method running for 10 years and it will still contain the same value.
You actually need to update the timestamp value each time you want to update it. If you were trying to limit the code in this method, you could do is change taskComplete to a method that returns a string with the updated timestamp
void SomeMethod()
{
//doing other stuff
using (StreamWriter w_Log = new StreamWriter(file_Log, true))
{
w_Log.WriteLine(GetTaskCompleteMessage());
w_Log.Close();
}
//doing other stuff
}
String GetTaskCompleteMessage()
{
string timeStamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ff");
return = (timeStamp) + " Task Complete";
}
you should redefine your string each time you want to update your log as you are doing now the variable timeStamp was fixed during the lifetime of your class's instance
string timeStamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ff");
string taskComplete = (timeStamp) + " Task Complete";
//here when you call the log method
using (StreamWriter w_Log = new StreamWriter(file_Log, true))
{
timeStamp = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.ff");
taskComplete = (timeStamp) + " Task Complete";
w_Log.WriteLine(taskComplete);
w_Log.Close();
}
Related
Console.WriteLine("What name would you like to be known as?");
string usernameforscore = Console.ReadLine();
string path = *filepath*;
File.WriteAllText(path, (usernameforscore + " " + classicscore + Environment.NewLine));
So this code is part of a game I'm making for a project, at the end of the game when you fail, I want it to save both a person's chosen username and their score (a variable saved somewhere else). I have got it to save the two to the file, however each time someone enters a new set of data, the file is overridden and only the new data is displayed.
I would like it to write a line with the name and score, then next time the code is run, it will display the new name and score on the next line, creating a high score list.
I'm using visual studio with a console program on C#
Apologies if this is a duplicate, couldn't seem to find a fix myself.
There is a method AppendAllText() rather than WriteAllText(), as below:
File.AppendAllText(#"c:\Path\filename.txt", "the text to append" + Environment.NewLine);
You can use the below method UpdateTextFile to save data to a text file.
public static void UpdateTextFile(string fileName, string content, bool doNotOverwrite = true, bool writeNewLine = true)
{
StreamWriter file = null;
using (file = new System.IO.StreamWriter(#"D:\" + fileName + ".txt", doNotOverwrite))
{
if (writeNewLine)
{
file.WriteLine(content);
}
else
file.Write(content);
file.Close();
}
}
Example of calling the method:
UpdateTextFile("FileName", "file-content", true, false);
Hope it helps.
I wrote an Async method in C# to write to a file, however I keep on getting the following exception:
The process cannot access the file
'C:\XXX\XXX\XXX\XXX\EventBuffer.txt' because it is being used by
another process.
I've had a look at similar questions already posted on SO such as this one, and this one but it seems like the cause of my issue is different.
I used a process monitor to see which processes are trying to access the directory in which the file is in but the only process trying to access it is the one I'm debugging (Will post a snippet soon of the debug process window).
It isn't that file access was being attempted before it was closed upon last access, because I can get the exception when I attempt to access the file for the first time. I have tried to implement a delay after the StreamWriter is instantiated incase the write method was being attempted, I wasn't using the using block before and was disposing of the object using it's dispose methods but in one of the similar questions a this solved the issue.
public static async void UpdateEventBufferFile(EventDetails EventDtls)
{
string line;
try
{
using (StreamWriter EventBufferFile = new StreamWriter(FilePath, true)) // creates the file
{
//All barcode data space sperated for split detection
line = EventDtls.SiteID + " " + EventDtls.McID + " " + EventDtls.EventID + " "
+ EventDtls.EventDT + " " + EventDtls.AdditionalInfo;
await Task.Run(() => LogFileManager.SystematicLog(" Events " + line + " added to buffer file", " BufferFileWriter.cs"));
await EventBufferFile.WriteLineAsync(line); //no need for new line char WriteLine does that
await EventBufferFile.FlushAsync();
//The using block is suffice to dispose of the object the below is no longer required
//EventBufferFile.Dispose();
//EventBufferFile.Close();
//EventBufferFile = null;
}
}
catch (Exception ex)
{
}
}
I have near identical methods utilised within other classes that don't cause the same issue, which annoys me quite a bit.
The method is not being invoked from within a Loop. Invocation is done in a seprate static class in the method below:
public static void AddCentralEvents(int SiteID, int McID, int EventID, DateTime EventDT, string AdditionalInfo)
{
EventDetails EventDetailsObj = new EventDetails();
EventDetailsObj.SiteID = SiteID;
EventDetailsObj.McID = McID;
EventDetailsObj.EventID = EventID;
EventDetailsObj.EventDT = EventDT;
EventDetailsObj.AdditionalInfo = AdditionalInfo;
Task.Run(() => BufferFileWriter.UpdateEventBufferFile(EventDetailsObj));
}
The error is self explanatory, you are using an ASYNC method (in a loop perhaps) and while your first task hasn't completed it's run (i.e. written to the file) that's why you are ending up with that error.
Have you tried writing with a synchronized method? If you have a requirement to periodically write to a file (i.e. logging) use a logging framework.
I recommend using log4net It is 'one of the' the best out there.
I'm working on a console application which is scheduled in windows scheduler to run every 15 minutes which when ran downloads a file from a public website using WebClient.
string Url1 = "http://www2.epa.gov/sites/production/files/" + DateTime.Now.Year + "-" + DateTime.Now.Month.ToString("d2")+ "/rindata.csv";
WebClient webClient = new WebClient();
webClient.DownloadFile(Url1, filename);
The above code works fine, but the above URL might or might not change every month randomly which cause my application throw 404 Exception.
Example
Consider the URL to be http://www2.epa.gov/sites/production/files/2015-09/rindata.csv and the variable part of the URL is 2015-09 which contains the data regarding September and it might change to 2015-10 for October if there any data change for that month but there no pattern of when or whether it changes everymonth.
May I know a better way to handle this?
To make it download every 15 minutes you can use a timer, set its interval to 15 minutes(in miliseconds), and put that code in the tick. Regarding the change of URL, I donĀ“t realize of a better way to do it.
It sounds like the URL won't necessarily update every month, so if this is the case don't re-evaluate the string every 15 minutes. So on first run set
string Url1 = "http://www2.epa.gov/sites/production/files/" + DateTime.Now.Year + "-" + DateTime.Now.Month.ToString("d2")+ "/rindata.csv";
you'll have to save this working value somewhere like the config file, then you can keep reusing this value until it fails, so every 15 minutes only run
WebClient webClient = new WebClient();
webClient.DownloadFile(Url1, filename);
instead of evaluating the URL again.
When it fails then re-evaluate it to the current month again.
if (failed)
{
string Url1 = "http://www2.epa.gov/sites/production/files/" + DateTime.Now.Year + "-" + DateTime.Now.Month.ToString("d2")+ "/rindata.csv";
}
then overwrite the saved value.
More info on saving to a settings file:
https://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
I regards to the Date change, I would probably do a backwards search from 12 to 1. Since the newest data is all you're interested in, a higher month that doesn't return a 404 would always be the freshest data. A simple loop that checks for a 404 would be fine if you have no other way to know what the URL is. This is a very basic example but the concept should be sound.
for (int i = 12; i > 1; i--)
{
string folder = string.Format("{0}-{1}", DateTime.Now.Year + "-" + i.ToString().PadLeft(2, '0'));
string Url1 = "http://www2.epa.gov/sites/production/files/" + folder + "/rindata.csv";
try
{
using (WebClient client = new WebClient())
{
client.DownloadFile(Url1, "/rindata.csv");
}
}
catch (Exception e)
{
Console.WriteLine(string.Format("404 Error:{0}", Url1));
}
}
namespace SimpleLicense
{
class Program
{
static void Main(string[] args)
{
string fileName = #"C:\\Temp\\test.txt";
try
{
// Check if file already exists. If yes, delete it.
if (File.Exists(fileName))
{
File.Delete(fileName);
}
// Create a new file
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
using (StreamWriter sw = File.CreateText(fileName))
{
sw.WriteLine("Thermo Licensing System file");
sw.WriteLine("------------------------------------");
sw.WriteLine("Installed Date: {0}", DateTime.Now.ToString());
DateTime newDate = DateTime.Now.AddDays(31);
sw.WriteLine("License Expires After"+" "+newDate);
sw.WriteLine("Number of Days Remaining ");
sw.Close();
// sw.WriteLine("Add ");
// sw.WriteLine("Done! ");
}
// Write file contents on console.
using (StreamReader sr = File.OpenText(fileName))
{
string s = "";
while ((s = sr.ReadLine()) != null)
{
Console.WriteLine(s);
}
Console.ReadLine();
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.ToString());
}
}
}
}
Contents of .txt File
Thermo Licensing System file
------------------------------------
Installed Date: 20-05-2014 16:01:42
License Expires After 20-06-2014 16:01:42
Number Of Days Remaining
Hi Everyone,
I have written the above code to store date and time information to a .txt file as given above.I want that the information about the remaining days be stored in .txt file.As you can see today's date is 20-5-2014 and the license expires on 20-6-2014.So 30 should be printed next to Number Of Days Remaining.
If the user changes the system clock,and changes the date to say 21-5-2014, then 29Days should be printed next to Number of Days remaining
I also want that when the application is executed on a particular date, the date should be set to that date ie at installed date and should not change and the remaining days be calculated on the basis of Installed date
Can anyone help me to figure this out?
Thanks
This code will give you the number of days:
int numberOfDays = newDate.Subtract(DateTime.Now).Days;
sw.WriteLine("Number of Days Remaining: " + numberOfDays.ToString());
you can used below menioned code
var Remainingdays=(LicenseExpires-InstalledDate).TotalDays
and if you want in int days then
var Remainingdays=(LicenseExpires-InstalledDate).Days
I assume you want to do time limited version of software?
While code posted in previous answers is technically correct, you probably shouldn't use DateTime.Now as user can tamper with system clock and circumvent your measure. Get current date from another source, like:
http://www.worldtimeserver.com/
This has its disadvantages though, like increased startup time and what if a page or user's connection is down?
Better and easier solution would be to forget about time limitation and limit amount of times application can be started instead. Then you simply load number on opening program and write decreased one on closing.
Also, storing relevant values as plaintext (with helpful user-friendly descriptions no less!) is probably not a good idea as any halfway savvy user may just snoop through files and edit them in any text editor. You may want to use some kind of encryption algorithm like AES:
http://msdn.microsoft.com/pl-pl/library/system.security.cryptography.aes%28v=vs.110%29.aspx
i am very new to C#, and this is my first question, please be gentle on me
I am trying to write a application to capture some tick data from the data provider, below is the main part of the program
void zf_TickEvent(object sender, ZenFire.TickEventArgs e)
{
output myoutput = new output();
myoutput.time = e.TimeStamp;
myoutput.product = e.Product.ToString();
myoutput.type = Enum.GetName(typeof(ZenFire.TickType), e.Type);
myoutput.price = e.Price;
myoutput.volume = e.Volume;
using (StreamWriter writer = File.AppendText("c:\\log222.txt"))
{
writer.Write(myoutput.time.ToString(timeFmt) + ",");
writer.Write(myoutput.product + "," );
writer.Write(myoutput.type + "," );
writer.Write(myoutput.price + ",");
writer.Write(myoutput.volume + ",");
}
i have successfully write the data into the text file, however i know that this method will be call like 10000 times a second during peak time, and open a file and append it many times a second is very inefficient, i was pointed to use a buffer or some sort, but i have no idea how to do it, i try reading the document but i still dont understand, thats why i turn in here for help.
Please give me some (working) snippet code so i can pointed to the write direction. thanks
EDIT: i have simplified the code as much as possible
using (StreamWriter streamWriter = File.AppendText("c:\\output.txt"))
{
streamWriter.WriteLine(string.Format("{0},{1},{2},{3},{4}",
e.TimeStamp.ToString(timeFmt),
e.Product.ToString(),
Enum.GetName(typeof(ZenFire.TickType), e.Type),
e.Price,
e.Volume));
}
ED has told me to make my stream to a field, how is the syntax looks like? can anyone post some code to help me? thanks a lot
You need to create a field for the stream instead of a local variable. Initialize it in constructor once and don't forget to close it somewhere. It's better to implement IDisposable interface and close the stream in Dispose() method.
IDisposable
class MyClass : IDisposable {
private StreamWriter _writer;
MyClass() {
_writer = File.App.....;
}
void zf_TickEvent(object sender, ZenFire.TickEventArgs e)
{
output myoutput = new output();
myoutput.time = e.TimeStamp;
myoutput.product = e.Product.ToString();
myoutput.type = Enum.GetName(typeof(ZenFire.TickType), e.Type);
myoutput.price = e.Price;
myoutput.volume = e.Volume;
_writer.Write(myoutput.time.ToString(timeFmt) + ",");
_writer.Write(myoutput.product + "," );
_writer.Write(myoutput.type + "," );
_writer.Write(myoutput.price + ",");
_writer.Write(myoutput.volume + ",");
}
public void Dispose() { /*see the documentation*/ }
}
There are many things you can do
Step 1. Make sure you don't make many io calls and string concatenations.
Output myOutput = new Outoput(e); // Maybe consruct from event args?
// Single write call, single string.format
writer.Write(string.Format("{0},{1},{2},{3},{4},{5}",
myOutput.Time.ToString(),
myOutput.Product,
...);
This I recommend regardless of what your current performance is. I also made some cosmetic changes (variable/property/class name casing. You should look up the difference between variables and properties and their recommended case etc.)
Step 2. Analyse your performance to see if it does what you want. If it does, no need to do anything further. If performance is still too bad, you can
Keep the file open and close it when your handler shuts down.
Write to a buffer and flush it at regular intervals.
Use a logger framework like log4net that internally handles the above for you, and takes care of hairy issues like access to the log file from multiple threads.
I would use String.Format:
using (StreamWriter writer = new StreamWriter(#"c:\log222.txt", true))
{
writer.AutoFlush = true;
writer.Write(String.Format("{0},{1},{2},{3},{4},", myoutput.time.ToString(timeFmt),
myoutput.product, myoutput.type, myoutput.price, myoutput.volume);
}
If you use # before string you don't have to use double \.
This is much faster - you write only once to the file instead of 5 times. Additionally you don't use + operator with strings which is not the fastest operation ;)
Also - if this is multithreading application - you should consider using some lock. It would prevent application from trying to write to the file from eg. 2 threads at one time.