从文件C#File.ReadAllLines中删除标题和预告片

时间:2017-02-20 17:39:12

标签: c#

我尝试读取文件并生成一个新文件,其中没有包含" HEADER"或" TRAILER"。以下是我的代码。当我在text [i] .Remove(i)上放置断点时,它似乎执行该代码但文本变量从不删除该行。任何帮助将不胜感激。

        var text = File.ReadAllLines(fileName);
        int i = 0;
        foreach (string line in text)
        {
            if (line.Substring(0, 20).Contains("HEADER") || line.Substring(0, 20).Contains("TRAILER"))
            {
                text[i].Remove(i);
            }
            else
            { 
            i++;
            }
        }
        string newFN = fileName + "b";
        File.WriteAllLines(newFN, text);

5 个答案:

答案 0 :(得分:1)

您无法在枚举器中更改可枚举。创建新的可写集合并仅插入与谓词匹配的行,或使用LINQ创建已应用条件的新枚举,然后将其映射到数组或列表或您需要的任何集合。

答案 1 :(得分:1)

ReadAllLines返回一个字符串数组。您可以使用LINQ从text

中选择新输出
var text = File.ReadAllLines(fileName).Select(i => {line.Contains("HEADER")? "": line});

File.WriteAllLines(newFN, text);

答案 2 :(得分:1)

File.WriteAllLines(filename + "b", File.ReadAllLines(filename)
    .Select(l => l.Substring(0, 20))
    .Where(s => !s.Contains("HEADER") && !s.Contains("TRAILER")));

您可以读取所有行,选择每行的前20个字符,然后使用Where排除前20个字符包含HEADER或TRAILER的所有行,然后将这些结果行写入文件

答案 3 :(得分:1)

我会使用ReadLines而不是ReadAllLines,因为它允许您在读取文件的更多行时进行枚举。这样,在开始写出新文件之前,您不必将整个文件读入内存。然后,您可以将代码简化为这一行:

File.WriteAllLines(fileName + "b", File.ReadLines(fileName).Where(line => !line.Contains("HEADER") | !line.Contains("TRAILER")));

这将导致它在写入新文件时遗漏HEADER和TRAILER行。

此外,为了更完整地回答您的问题,String.Remove将从索引中删除所有字符到字符串末尾并返回一个新字符串。 .Net中的字符串是不可变的,因此它不会修改当前字符串,只需返回一个新字符串即可。此外,当您在比较中调用Substring时,这些方法正在创建新的字符串实例,以便您检查字符串是否包含在该字符串中。最好只在字符串上调用Contains

答案 4 :(得分:1)

var lines = File.ReadLines(fileName);
var filtered = lines.Where(line => !line.Contains("HEADER") && !line.Contains("TRAILER")));
File.WriteAllLines(filename + "b", filtered);     // or filename.Replace(".txt", "b.txt") ?

.Substring(0, 20)为新字符串分配内存,对于少于20个字符的行会失败,因此在大多数情况下,只有.Contains会更快。或者,您可以改为使用.IndexOf

line.IndexOf("HEADER", 0, 20, StringComparison.OrdinalIgnoreCase) < 0

我猜测,通过避免一些额外的内存分配,RegEx可能会更快一些:

string text = File.ReadAllText(fileName);
string[] parts = Regex.Split(text, @"\n?\r?.*(HEAD|TRAIL)ER.*\n?\r?");
File.WriteAllLines(filename + "b", parts);