我需要从文本文件中读取并仅从中获取某些数据。文本文件有多行,类似于下面的
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&#34 ;和" \ 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;
答案 0 :(得分:3)
可能的解决方案
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;
当然,这假设您的日期部分完全采用上述格式,并且路径中的数字只在该位置出现一次。
答案 1 :(得分:1)
如果所有行都相同,您可以使用这些内容获取日期和数字:
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\
部分(这是数字后面的最小唯一部分)。 -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
,您可以使用。{/ p>来提供行。{/ p>
之后有多种方法可以添加您的值,但如果我们按照您的操作(手动将每个条目添加为一行),您可以通过使用for
循环遍历值来实现该结果:< / p>
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]
。
答案 2 :(得分:0)
如果“12/05/2014 06:51 c:\ BACKUPS \ INT1000 \ BACKUP \ BACKUP.ZIP”是一致的格式,那么您可以这样做,假设Lines是一个带有文件行的字符串[]:
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",""));
}
如果您的路径并不总是相同,我可以为您提供另一个示例。
答案 3 :(得分:0)
如果您正在使用DataTable,您还可以使用OLEDB来处理文本文件,就像数据库一样。您将使用SQL查询与该文件进行交互。
只需导入System.Data.OleDb并像使用任何其他数据库一样使用OleDb对象(连接,datareader等)。当然,您不会有存储过程,但可以使用参数化查询。
如果您使用正确的连接字符串,这也适用于Excel文件。
了解更多信息: http://www.connectionstrings.com/textfile/
这不是一直都是正确的方法,但有时它就是你所需要的。