只读文本文件中的某些列

时间:2015-02-11 14:54:19

标签: c# winforms streamreader

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

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;

4 个答案:

答案 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/

这不是一直都是正确的方法,但有时它就是你所需要的。