Reputation: 969
I need to read from a text file and only get certain data from it. The text file has multiple lines, similar to below
12/05/2014 06:52 c:\BACKUPS\INT100\BACKUP\BACKUP.ZIP
12/05/2014 06:51 c:\BACKUPS\INT1000\BACKUP\BACKUP.ZIP
I need the date, time and the number (in this case 100 and 1000), but can't figure out how to get rid of the other stuff like "c:\backups\INT" and "\BACKUP\BACKUP.ZIP".
I thought of using a substring method but it will only partially work really. Plus the INT number can be between 1-9999.
This is what I've got at the moment read data from text file into DataTable
and then into a GridView
:
StreamReader readData = new StreamReader(@"c:\Users\1484814\desktop\date.txt");
DataTable listOFDates = new DataTable();
listOFDates.Columns.Add("Dates");
while (!readData.EndOfStream)
{
string shortenLine = readData.ReadLine();
// shortenLine = shortenLine.Substring(0, 35);
listOFDates.Rows.Add(shortenLine);
}
gv_textFile.DataSource = listOFDates;
Upvotes: 0
Views: 1708
Reputation: 9201
If all lines are the same, you can get the dates and then the numbers with those one liners:
var text = File.ReadAllLines(@"c:\Users\1484814\desktop\date.txt");
var dates = text.Select(line => DateTime.Parse(line.Substring(0, 16)));
var numbers = text.Select(line => line.Substring(31, line.IndexOf(@"\BACKUP\") - 31));
For the dates, you take the start of string and parse it to a DateTime
.
For the numbers, get to the number index, then take stuff until you hit the \BACKUP\
part (which is the minimal unique part after the number). The -31
is because Substring
takes a length
, not an end index.
If you extract the magic numbers:
const int END_OF_DATE = 16;
const int START_OF_NUMBER = 31;
var text = File.ReadAllLines(@"c:\Users\1484814\desktop\date.txt");
var dates = text.Select(line => DateTime.Parse(line.Substring(0, END_OF_DATE)));
var numbers = text.Select(line => line.Substring(START_OF_NUMBER, line.IndexOf(@"\BACKUP\") - START_OF_NUMBER));
You end up with two IEnumerable
s, which you can feed your rows with.
There's multiple ways to add your value afterwards, but if we follow what you were doing (adding manually each entry as a row), you could achieve that result by looping over the values with a for
loop:
DataTable listOFDates = new DataTable();
listOFDates.Columns.Add("Dates");
listOFDates.Columns.Add("Numbers");
for (int i = 0; i < dates.Count(); i++)
{
listOFDates.Rows.Add(dates[i], numbers[i]);
}
We can safely iterate both lists with the same index since we know they have the same size.
However this method requires you transform the previous LINQ queries into a list by adding .ToList()
and the end of both dates and numbers queries. If you wish to keep it as a generic IEnumerable
instead of a list, you can use .ElementAt(i)
instead of [i]
.
Upvotes: 1
Reputation: 4101
If you're working with a DataTable, you can also use OLEDB to work with the text file like a database. You'd interact with the file using SQL queries.
Just import System.Data.OleDb and use the OleDb objects (connection, datareader, etc) like you would any other database. You won't have stored procedures, of course, but you can use parameterized queries.
This also works for Excel files if you use the right connection string.
For more information: http://www.connectionstrings.com/textfile/
This isn't the right approach all the time, but sometimes it's what you need.
Upvotes: 0
Reputation: 216303
A possible solution
StreamReader readData = new StreamReader(@"c:\Users\1484814\desktop\date.txt");
DataTable listOFDates = new DataTable();
listOFDates.Columns.Add("Dates", typeof(DateTime));
listOFDates.Columns.Add("Numbers", typeof(int));
while (!readData.EndOfStream)
{
string line = readData.ReadLine();
string[] parts = line.Split(' ');
DateTime dt = DateTime.ParseExact(string.Join(" ", parts[0], parts[1]), "dd/MM/yyyy hh:mm", CultureInfo.CurrentCulture, DateTimeStyles.None);
int number = Convert.ToInt32(Regex.Match(parts[2], @"\d+").Value);
listOFDates.Rows.Add(new object[] {dt, number});
}
gv_textFile.DataSource = listOFDates;
Of course, this assumes that your date part is exactly always in the above format and that your numbers inside the path are just present one time in that position.
Upvotes: 3
Reputation: 424
If "12/05/2014 06:51 c:\BACKUPS\INT1000\BACKUP\BACKUP.ZIP" is a consistent format, then you can do, assuming Lines is a string[] with the lines of your file:
string[] Lines= File.ReadAllLines("file.txt");
foreach(var Line in Lines)
{
string[] Parameters= Line.Split(' ');
string Date= Parameters[0];
string Time= Parameters[1];
string[] PathInfo= Parameters[2].Split('\\');
int Number= Convert.ToInt32(PathInfo[2].Replace("Int",""));
}
If your path isn't always the same I can provide you with another example.
Upvotes: 0