2015-10-02 4 views
-3

Моя цель - прочитать текстовый файл (< 50 мб) и выполнить на нем регулярное выражение, а затем сохранить его обратно в другой файл (в C#). Как я делаю это, опубликовано ниже.C# не может прочитать текстовый файл (не очень большой) (IndexOutOfRange)

Regex regex = new Regex(@"\s{2,}"); 
var lines = File.ReadLines(path); 
     foreach (var line in lines) 
     { 
      Console.WriteLine(regex.Split(line,2)[1]); 
      File.WriteAllText(regex.Split(line,2)[1]);      
     } 

Когда я пробую это с небольшим файлом (140 КБ), он отлично работает. Когда я запускаю то же самое с файлом размером ~ 50 МБ, он вылетает Есть ли у него что-нибудь с выполнением регулярного выражения внутри цикла?

IndexOutOfRange - это исключение, которое выбрасывается. Что я не могу понять, так это то, как файл размером 45 Мбайт может отключить мою систему из памяти? У меня установлено 8 гигабайт оперативной памяти.

+1

Сплит() не возвращает массив с элементом по индексу 1 –

+5

Прочитайте исключение. Проверьте трассировку стека. Изолируйте код. Например, вы можете ввести переменную 'string [] split = regex.Split (строка, 2)', а затем проверить, что этот массив фактически имеет два элемента. – CodeCaster

+0

Не то, чтобы это ваша проблема ... но когда вы используете VS, у нее останется только столько памяти для программы. [Статья] (http://blogs.msdn.com/b/calvin_hsia/archive/2010/09/27/10068359.aspx). – ryuu9187

ответ

1

Должна быть линия, где regex.Split(line,2)[1] - null. Добавить проверку

Regex regex = new Regex(@"\s{2,}"); 
var lines = File.ReadLines(path); 

foreach (var line in lines) 
{ 
    var item = regex.Split(line,2); 
    if(item.Length > 1) 
    { 
      Console.WriteLine(regex.Split(line,2)[1]); 
      File.WriteAllText(regex.Split(line,2)[1]); 
    }     
} 

и он должен работать

+0

Нет, split не будет выдавать «нулевые» записи, а «null» не будет выбрасывать указанное исключение. Этот код будет работать с тестом '> 1'. – CodeCaster

+0

Хорошо, я не был уверен, поэтому добавил его для полноты. Ответ обновлен – Nick

+0

Протестировано, нет выхода. Blank! – Sid

0

IndexOutOfRange выбрасывается при попытке получить доступ к индексу массива, который не существует. Ваш код имеет доступ к массиву в массиве, возвращаемом вызовами Split(). Таким образом, вероятно, что вы терпите неудачу, когда Split() возвращает массив с менее чем двумя элементами, так что индекс 1 недействителен. Обратите внимание, что вторым аргументом Split является только МАКСИМАЛЬНОЕ число разделов: минимального нет. Вы можете выполнить дополнительную проверку на своем входе или сделать что-то вроде .Last() вместо [1].

+0

Добавление .last вместо [1] действительно сработало, но строка появляется как есть, а не делится на две. – Sid

+0

@Sid: в точке, где это происходит, каково значение строки? – ChaseMedallion

0

После того, как вы исправили свою первую проблему со ссылкой на неверный индекс, у вас возникнет проблема с постоянным вызовом File.WriteAllText в цикле. Это решает обе проблемы и не сохраняет открытие/закрытие целевого файла.

Regex regex = new Regex(@"\s{2,}"); 
File.WriteAllLines(path2,File.ReadLines(path).Select(line=>{ 
    var items=regex.Split(line,2); 
    return items.Length>1?item[1]:""; 
})); 
+0

Что может быть p? Я не уверен, что будет файлом здесь? – Sid

+0

@Sid К сожалению, p должен был быть строчным, фиксированным. –

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