只读文本文件中的某些列(Read only certain columns from a text file)

我需要从文本文件中读取并仅从中获取某些数据。 文本文件有多行,类似于下面

12/05/2014 06:52 c:\BACKUPS\INT100\BACKUP\BACKUP.ZIP 
12/05/2014 06:51 c:\BACKUPS\INT1000\BACKUP\BACKUP.ZIP
 

我需要日期,时间和数字(在这种情况下为100和1000),但无法弄清楚如何摆脱其他东西,如“c:\ backups \ INT”和“\ BACKUP \ BACKUP.ZIP” 。

我想过使用子字符串方法,但它只能部分工作。 此外,INT编号可介于1-9999之间。

这就是我现在从文本文件中读取数据到DataTable然后到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;

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;

最满意答案

如果所有行都相同,您可以使用这些内容获取日期和数字:

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));

对于日期,您将获取字符串的开头并将其解析为DateTime 。

对于数字,转到数字索引,然后取出东西,直到你点击\BACKUP\ part(这是数字后面的最小唯一部分)。 -31是因为Substring采用length而不是结束索引。

如果你提取幻数:

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));

你最终得到了两个IEnumerable ,你可以用你的行。

之后有多种方法可以添加您的值,但如果我们按照您的操作(手动将每个条目添加为一行),您可以通过使用for循环遍历值来实现该结果:

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]); }

我们可以安全地使用相同的索引迭代两个列表,因为我们知道它们具有相同的大小。

但是,此方法要求您通过添加.ToList()以及日期和数字查询的结尾将先前的LINQ查询转换为列表。 如果您希望将其保留为通用IEnumerable而不是列表,则可以使用.ElementAt(i)而不是[i] 。

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 IEnumerables, 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].

更多推荐