if statements to evaluate multiple file dates - c#

I am new to C# (less than a week), I have the following code that deletes a file on a volume. It is a back up file for an SQL database. And it keeps growing so periodically I have to rename the file and then delete it after a new file is backed up. I need to evaluate if the backup ran and then it is okay to delete the file.
using System;
using System.IO;
class Program
{
static void Main()
{
//
// Delete a file found on the D:\ volume.
// If the file is not found (File doesn't exist),
// then you will get an exception.
//
try
{
File.Delete(#"\\Fabtrol-2\Program Files (x86)\FabTrolBackUp\FT_Trans_Log_Appendedold.BAK"); // Try to delete
Console.WriteLine("Deleted"); // Success
}
catch (IOException ex)
{
Console.WriteLine(ex); // Write error
}
}
}
This is the logic. If I'm asking too much let me know:
If todays date is = Monday and file FT_FabTrol_Sun_Full.BAK ‘s date is less than 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK
Else If todays date is = Tuesday and file FT_FabTrol_Mon_Full.BAK ‘s date is less than 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK
Else If todays date is = Wednesday and file FT_FabTrol_Tues_Full.BAK ‘s date is less than 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK
Else If todays date is = Thursday and file FT_FabTrol_Wed_Full.BAK ‘s date is less than 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK
Else If todays date is = Friday and file FT_FabTrol_Thurs_Full.BAK ‘s date is less then 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK
Else If todays date is = Saturday and file FT_FabTrol_Fri_Full.BAK ‘s date is less than 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK
Else If todays date is = Sunday and file FT_FabTrol_Sat_Full.BAK ‘s date is less than 2 days old then it is okay to delete the file named FT_Trans_Log_Appendedold.BAK

You can simplify that logic greatly with: -
FileInfo info = new FileInfo(#"\\Fabtrol-2\Program Files (x86)\FabTrolBackUp\FT_Trans_Log_Appendedold.BAK");
if(DateTime.Now.AddDays(-2) > info.LastWriteTime.Date)
{
//Delete
}

All you need to do is iterate over all the files in your folder and delete the ones that are older than two days, right (that seems to be what your giant conditional statement comes down to)?
So, use the following line to get all the files in the folder:
string[] files = Directory.GetFiles(<folder name>);
Then, in a loop, iterate over all the file names in files and check, whether they are old enough.
To get the timestamp of the file, use FileInfo and LastWriteTime like this:
if(DateTime.Today - someFileInfoObject.LastWriteTime.Date > new TimeSpan(2,0,0,0))
{
File.Delete();
}

This code 1st checks if the file based on the day is less than 2 days old, then if it is it deletes the file FT_Trans_Log_Appendedold.BAK.
string dir = #"\\Fabtrol-2\Program Files (x86)\FabTrolBackUp\";
string fileName = dir;
switch (DateTime.Now.DayOfWeek)
{
case DayOfWeek.Monday:
fileName += "FT_FabTrol_Sun_Full.BAK";
break;
case DayOfWeek.Tuesday:
fileName += "FT_FabTrol_Mon_Full.BAK";
break;
case DayOfWeek.Wednesday:
fileName += "FT_FabTrol_Tues_Full.BAK";
break;
case DayOfWeek.Thursday:
fileName += "FT_FabTrol_Wed_Full.BAK";
break;
case DayOfWeek.Friday:
fileName += "FT_FabTrol_Thurs_Full.BAK";
break;
case DayOfWeek.Saturday:
fileName += "FT_FabTrol_Fri_Full.BAK";
break;
case DayOfWeek.Sunday:
fileName += "FT_FabTrol_Sat_Full.BAK";
break;
}
FileInfo fi = new FileInfo(fileName);
if (fi.Exists && DateTime.Now.AddDays(-2) > fi.LastWriteTime.Date)
{
(new FileInfo(dir + "FT_Trans_Log_Appendedold.BAK")).Delete();
Console.WriteLine("Deleted");
}

Personally for one weeks experience I would say you've jumped into the deep end.
I'm not going to provide code, rather direct you to improve your learning, this is referred to psuedo code
Look into streamwriter/reader and filewriter and fileinfo.
From this you can then read files, delete/rename/whatever you want really.
You then need to try and understand how could I validate what I'm doing.
Unfortunately for a beginner this is harder than you may think, possibly harder than the first two points for some people. Think from simple onwards, we developers usually over complicate things. This part is actually rather easy so long your file stuff is correct!
You may want to look into unit testing as this may help your validation.

Building on what #Gray commented, the FileInfo object will also let you know if it .Exists or not, alleviating the need to depend on the try/catch to know if a file is still there.
Consider the following:
static void Main()
{
FileInfo fi = new FileInfo(#"\\path\\to\\file.bak");
if(fi.Exists)
{
try
{
//because we can still get errors based on permissions etc.
fi.Delete();
Console.WriteLine("Deleted"); // Success
}
catch (IOException ex)
{
Console.WriteLine(ex); // Write error
}
}
}

Try below code.
string backupFile = #"\\Fabtrol-2\Program Files (x86)\FabTrolBackUp\FT_Trans_Log_Appendedold.BAK";
FileInfo fi = new FileInfo(backupFile);
DateTime fileCreatedDate = File.GetCreationTime(backupFile);
DateTime today = DateTime.Now;
if (today.DayOfWeek != DayOfWeek.Monday && fileCreatedDate > today.AddDays(-2))
{
fi.Delete();
}

Updated my answer to meet your requirements. Kinda weird, but I was bored. May be helpful if just to read.
//2 days
TimeSpan daysToKeep = new TimeSpan(2,0,0,0);
//The folder where the files are kept
DirectoryInfo backupFolder = new DirectoryInfo(#"\\Fabtrol-2\Program Files (x86)\FabTrolBackUp\");
//the Appendold.BAK file
FileInfo backupLog = new FileInfo(backupFolder.FullName + #"\FT_Trans_Log_Appendedold.BAK");
//the base name for the log files
string logName = "FT_FabTrol_{0}_Full.BAK";
//an array for the days of week that are part of the logname
string[] days = { "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat" };
//get yesterday's log file name
string yesterdayLog = String.Format(logName, days[(int)DateTime.Today.AddDays(-1).DayOfWeek]);
//create file info
FileInfo logFile = new FileInfo(backupFolder.FullName + yesterdayLog);
//if the file exists, and it is less than 2 days old
try
{
if (logFile.Exists && (DateTime.Today - logFile.LastWriteTime < daysToKeep))
{
backupLog.Delete();
Console.WriteLine("success");
}
else
{
Console.WriteLine("log file either did not exist or is not ready to delete");
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}

Related

Ignore Empty files C#

I am trying to avoid empty files in my Program and the way i am doing it doesnt work.
I got a machschine that create logs, at Weekend is nobody here and but the maschine create a file with only 5,6 lines, the right one should have 20k lines.
I know there is FileInfo.Length but i dont know how to use it with this what a have right now.
public List<SystemLogFileData> ProcessSystemLogFiles(List<string> systemLogsFilePaths)
{
List<SystemLogFileData> systemLogFilesData = new List<SystemLogFileData>();
foreach (var filePath in systemLogsFilePaths)
{
string[] lines = System.IO.File.ReadAllLines(filePath);
var systemLogFileData = ProcessSystemLogFile(lines.ToList());
if (File.ReadAllText(systemLogFileData).Length > 100)
{
systemLogFilesData.Add(systemLogFileData);
}
}
return systemLogFilesData;
}
I solved it and it works well. Not in my main Program but in Autobackup.
insted of ignoring the the not important file i don't copy them and i reached my goal.
Thakns for the help!
//path of file
string pathToOriginalFile = #"C:\Users\Desktop\c#\Logging\Systemlog.bk66";
//duplicate file path
string PathForDuplicateFile = #"C:\\\Desktop\c#\Systemlog";
//rename fileName if Exists
FixFileName(ref PathForDuplicateFile, ".bk");
if (File.ReadAllText(pathToOriginalFile).Length > 2000)
{
File.Copy(pathToOriginalFile, PathForDuplicateFile);
}
else
{
}
//provide source and destination file paths

Running the scheduler twice is updating the file with the earlier file in Console application C#

I have a requirement where my scheduler will run twice in a day. One in the morning and a second time in evening. When I run my current code it stores the file in a folder.
So again when I run the same application in the evening what happens is that the same file which is saved earlier in the morning is getting updated again which I don't want to happen. I want to save both the files. So what should I do?
Below is my current code. Please give me suggestions
public void ExportExcel(string strWorkbookName, DataSet ds)
{
string strDateFolder = "";
string strFileName = ConfigurationManager.AppSettings["FileName"].ToString();
try
{
using (XLWorkbook wb = new XLWorkbook())
{
strDateFolder = DateTime.Now.ToString("dd-MM-yyyy");
if (Directory.Exists(strDateFolder))
{
Directory.CreateDirectory(strDateFolder);
}
wb.Worksheets.Add(ds);
wb.SaveAs(ConfigurationRead.GetAppSetting("ReportDirectory") + "\\" + strDateFolder + "\\" + strFileName);
}
}
catch (Exception)
{
throw;
}
}
UPDATE
Also, I want to delete the folder created after 7 days..Is that also possible ?
strDateFolder will contain the same value through both runs because it gets the date. You may want to add time to that so it creates another file. Like this:
strDateFolder = DateTime.Now.ToString("dd-MM-yyyy-hh");
Then, the code below is like saying: if this directory exists, create it.
if (Directory.Exists(strDateFolder))
{
Directory.CreateDirectory(strDateFolder);
}
You can use only this, because it will create it only if it does not exist:
Directory.CreateDirectory(strDateFolder);
Update from post:
This would delete your folders older that 6 days
CultureInfo enUS = new CultureInfo("en-US");
string path = ConfigurationRead.GetAppSetting("ReportDirectory");
DateTime currentDate = DateTime.Now.AddDays(-7);
foreach (string s in Directory.GetDirectories(path))
{
string folderPath = s.Remove(0, path.Length);
if (DateTime.TryParseExact(folderPath, "dd-MM-yyyy hhmmss", enUS, DateTimeStyles.AssumeLocal, out DateTime td))
{
if (td <= currentDate)
{
Directory.Delete(s, true);
}
}
}

Check if folder contains files with certain extensions

I have other C# code that drops a call recording file into the folder c:\Recordings
Each file has the extension of .wma
I'd like to be able to check the folder every 5 minutes. If the folder contains a file ending in .wma i'd like to execute some code.
If the folder does not contain a file with the .wma extension, i'd like the code to pause for 5 minutes and then re-check (infinitely).
i've started with the following the check if the folder has any files in it at all, but when I run it, it always reports the folder contains files, even though it does not.
string dirPath = #"c:\recordings\";
if (Directory.GetFiles(dirPath).Length == 0)
{
NewRecordingExists = true;
Console.WriteLine("New Recording exists");
}
else
{
NewRecordingExists = false;
Console.WriteLine("No New Recording exists");
System.Threading.Thread.Sleep(300000);
}
if (Directory.GetFiles(dirPath).Length == 0)
This is checking if there are no files... then you are reporting "New Recording exists". I think you just have your logic the wrong way around. else is where it means you have found some files.
In addition, if you want to check for just *.wma files then you can use the GetFiles overload that takes a search pattern parameter, for example:
if (Directory.GetFiles(dirPath, "*.wma").Length == 0)
{
//NO matching *.wma files
}
else
{
//has matching *.wma files
}
SIDE NOTE: You may be interested in the FileSystemWatcher, this would enable you to monitor your recordings folder for changes (including when files are added). This would eliminate your requirement to poll every 5 minutes, and you get near-instant execution when the file is added, as opposed to waiting for the 5 minute interval to tick over
First of all your logic is reversed! ;)
here is you correct code:
bool NewRecordingExists;
string dirPath = #"c:\recordings\";
string[] fileNames = Directory.GetFiles(dirPath, "*.wma", SearchOption.TopDirectoryOnly);
if (fileNames.Length != 0)
{
NewRecordingExists = true;
foreach (string fileName in fileNames)
{
Console.WriteLine("New Recording exists: {0}", fileName);
/* do you process for each file here */
}
}
else
{
NewRecordingExists = false;
Console.WriteLine("No New Recording exists");
System.Threading.Thread.Sleep(300000);
}
Although, i recommend using System.Timers.Timer class for you application!
Don't use GetFiles if you're going to throw the result away.
Use an enumeration so you can exit early:
Directory.EnumerateFiles(Folder, "*.wma", SearchOption.AllDirectories).FirstOrDefault() != null

Retrieve Date Information from a .txt file using c#

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

Reading and writing dates to the registry for trial version purposes

Here's what I want to do, I want to store the date the first time the program is installed and also store a date when was the program was last run. I want the code to check to see if it was more than 30 days since the installation so I can turn off features. I also want to check if the system date is less than the last opened date and if so write the installed date to 1/1/1901 to prevent the program from running.
Keeping in mind that this is not a consumer program but a business program I don't expect hackers to crack it, they may do but that is fine I simply want to give potential customers a reason to consider purchasing the program and the end of the trial will prompt this.
Q1: Does this sound reasonable?
Q2: How should I hide the fact these are dates so it's not easily identified and changed?
Many thanks
Lee
The Microsoft.Win32 namespace is what you need. You will want to look at the two following classes: Registry and RegistryKey.
You could store the hash code of your date within the registry key you will use.
Except that I would neither place it in the registry. The AppData folder is a better place, in addition to your local installation folder. Perhaps will you want to to use binaries with the System.IO namespace so that you can write binary data. The BinaryWriter and BinaryReader classes are probably what you will need to do this.
I would suggest the hidden common application data directory instead of the registry. And write the dates in binary format:
static string appDataFile;
static void Main(string[] args)
{
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
appDataPath = System.IO.Path.Combine(appDataPath, "MyApplication");
if (!System.IO.Directory.Exists(appDataPath))
System.IO.Directory.CreateDirectory(appDataPath);
appDataFile = System.IO.Path.Combine(appDataPath, "History.dat");
DateTime[] dates;
if (System.IO.File.Exists(appDataFile))
dates = ReadDates();
else
dates = new DateTime[] {DateTime.Now, DateTime.Now};
Console.WriteLine("First: {0}\r\nLast: {1}", dates[0], dates[1]);
dates[1] = DateTime.Now;
WriteDates(dates);
}
static DateTime[] ReadDates()
{
System.IO.FileStream appData = new System.IO.FileStream(
appDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
List<DateTime> result = new List<DateTime>();
using (System.IO.BinaryReader br = new System.IO.BinaryReader(appData))
{
while (br.PeekChar() > 0)
{
result.Add(new DateTime(br.ReadInt64()));
}
br.Close();
}
return result.ToArray();
}
static void WriteDates(IEnumerable<DateTime> dates)
{
System.IO.FileStream appData = new System.IO.FileStream(
appDataFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);
List<DateTime> result = new List<DateTime>();
using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(appData))
{
foreach(DateTime date in dates)
bw.Write(date.Ticks);
bw.Close();
}
}
I would not store this in the registry because it's really easy to change (at least in the places you can write). I would write it in the Local Data folder in a little file and encrypt it. Probably store it in a couple of places in case someone deletes the file.

Categories

Resources