只读取文本文件中的某些列
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:\Users84814\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;
如果 "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",""));
}
如果您的路径并不总是相同的,我可以为您提供另一个示例。
可能的解决方案
StreamReader readData = new StreamReader(@"c:\Users84814\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;
当然,这假设您的日期部分始终采用上述格式,并且路径中的数字仅在该位置出现一次。
如果所有行都相同,您可以获得日期,然后是那些行的数字:
var text = File.ReadAllLines(@"c:\Users84814\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:\Users84814\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]
。
如果您正在使用 DataTable,您还可以使用 OLEDB 来像处理数据库一样处理文本文件。您将使用 SQL 查询与文件交互。
只需导入 System.Data.OleDb 并像使用任何其他数据库一样使用 OleDb 对象(连接、数据读取器等)。当然,您不会有存储过程,但是您可以使用参数化查询。
如果您使用正确的连接字符串,这也适用于 Excel 个文件。
更多信息:
http://www.connectionstrings.com/textfile/
这并非始终是正确的方法,但有时它正是您所需要的。
我需要从一个文本文件中读取并且只从中获取某些数据。文本文件有多行,类似下面
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:\Users84814\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;
如果 "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",""));
}
如果您的路径并不总是相同的,我可以为您提供另一个示例。
可能的解决方案
StreamReader readData = new StreamReader(@"c:\Users84814\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;
当然,这假设您的日期部分始终采用上述格式,并且路径中的数字仅在该位置出现一次。
如果所有行都相同,您可以获得日期,然后是那些行的数字:
var text = File.ReadAllLines(@"c:\Users84814\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:\Users84814\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]
。
如果您正在使用 DataTable,您还可以使用 OLEDB 来像处理数据库一样处理文本文件。您将使用 SQL 查询与文件交互。
只需导入 System.Data.OleDb 并像使用任何其他数据库一样使用 OleDb 对象(连接、数据读取器等)。当然,您不会有存储过程,但是您可以使用参数化查询。
如果您使用正确的连接字符串,这也适用于 Excel 个文件。
更多信息: http://www.connectionstrings.com/textfile/
这并非始终是正确的方法,但有时它正是您所需要的。