То, что я ищу, - это что-то в этом роде:
var f = UsefulFileObject(@"c:\temp.log");
f.ForEachLine( (line) => line.Trim() );
После этого я ожидаю, что каждая строка в файле будет обрезана.
Есть ли такой объект в структуре уже или я должен начать создавать свой собственный?
После просмотра нескольких неправильных решений с использованием ForEach
в неизменяемом типе, например string
, я предполагаю, что опубликую мои собственные.
Это будет фактически читать и записывать упомянутый файл. Тем не менее, это для небольших файлов, так как все содержимое будет в памяти *.
string filename = @"C:\testfile.txt";
string[] fileLines = File.ReadAllLines(filename);
fileLines = Array.ConvertAll(fileLines, l => l.Trim());
File.WriteAllLines(filename, fileLines);
В реальном мире вы, вероятно, захотите сначала записать в другой файл и переименовать его в исходный файл после завершения операции. В противном случае части файла могут быть потеряны, если что-то пошло не так, как на полпути.
Использование памяти объявлений:
Фактически, файл будет в памяти дважды на мгновение. Вы можете решить это, используя обычный цикл for
вместо любых причудливых методов расширения и лямбда-выражений. Я пропущу это упражнение и перейду к "правильному" способу сделать это для больших файлов:
using (StreamReader reader = new StreamReader(@"D:\infile.txt"))
using (StreamWriter writer = new StreamWriter(@"D:\outfile.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
writer.WriteLine(line.Trim());
}
}
// Some File.Move(..) usage to rename the files
Реализация "ForEachLine" :
Если вы хотите реализовать вспомогательный метод, который делает то, что вы описали, вы можете скрыть уродливую логику переименования.
Подпись метода будет выглядеть примерно так:
public void ForEachLine(Func<string, string> func)
и строка, выполняющая запись, будет выглядеть следующим образом:
writer.WriteLine(func(line));
Поскольку вы не можете изменить текстовый файл на месте (ну, очевидно, вы можете, но это просто тяжело), такой объект будет в основном сосредоточен вокруг системы read-modify-write.
Для довольно небольших файлов используйте File.ReadAllLines(filename).ForEach(l = > l.Trim())
У вас есть метод System.IO.File.ReadAllLines(), который возвращает строку [] (массив строк).
Затем массив можно использовать с циклом foreach, который вы можете преобразовать в список и использовать метод ForEach (Action).
Итак, это должно работать:
string[] logLines = System.IO.File.ReadAllLines(@"c:\temp.log");
logLines.ToList().ForEach(l => l.Trim());
logLines
фактически не изменяется вообще.