2015-02-11 2 views
0

Мне нужно прочитать из текстового файла и получить от него определенные данные. Текстовый файл имеет несколько линий, аналогичные нижеЧтение только определенных столбцов из текстового файла

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; 
+2

У него есть «много линий» или «все линии», как показано на примере, который вы показали? Всегда ли путь всегда (кроме номера)? –

+0

Вы знакомы с 'string.Split()' – MethodMan

+0

Путь yeah - это всегда одно и то же единственное, что меняется - дата и номер int (INT100, INT101, INT103 и т. Д.) – wubblyjuggly

ответ

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 с, что вы можете кормить строк с.

Там в несколько способов, чтобы добавить свою ценность после этого, но если мы будем следовать, что вы делаете (добавление вручную каждую запись в качестве строки), вы могли бы достичь этого результата с помощью цикла по значениям с 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]); 
} 

Мы можем безопасно перебирать оба списка с тем же индексом, так как мы знаем, что они имеют одинаковый размер.

Однако для этого метода необходимо преобразовать предыдущие запросы LINQ в список, добавив .ToList() и конец как запросов даты, так и числа. Если вы хотите сохранить его как общий IEnumerable вместо списка, вы можете использовать .ElementAt(i) вместо [i].

+0

Это похоже на хорошее решение, но я не уверен как получить значения из двух IEnumerables? – wubblyjuggly

0

Если «12/05/2014 6:51 C: \ BACKUPS \ INT1000 \ BACKUP \ BACKUP.ZIP»является последовательным форматом, то вы можете сделать, предполагая, что линии является строка [] с линиями файла:

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

Возможное решение

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; 

Конечно, это предполагает, что ваша дата часть точно всегда в указанном выше формате и что ваши номера внутри пути просто присутствует один раз в этом положении.

0

Если вы работаете с DataTable, вы также можете использовать OLEDB для работы с текстовым файлом, например с базой данных. Вы должны взаимодействовать с файлом, используя SQL-запросы.

Просто импортируйте System.Data.OleDb и используйте объекты OleDb (соединение, datareader и т. Д.), Как и любая другая база данных. Конечно, у вас не будет хранимых процедур, но вы можете использовать параметризованные запросы.

Это также работает для файлов Excel, если вы используете правильную строку соединения.

Для получения дополнительной информации: http://www.connectionstrings.com/textfile/

Это не правильный подход все время, но иногда это то, что вам нужно.

Смежные вопросы