在c#中使用另一个文件从一个文件中删除字符串

时间:2017-11-04 16:55:59

标签: c#

我有两个文件,即file.txt和database.xml

file.txt看起来像

Istanbul
Moscow
London
Saint Petersburg
Berlin
Madrid
Kiev
Rome
Paris

database.xml看起来像

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<city-group>
    <city>Paris</city>
    <city>London</city>
    <city>Boulder</city>
    <city>Mumbai</city>
    <city>Quebec</city>
    .....
    .....
</city-group>

如何使用database.xml搜索file.txt中每行的内容,如果它们之间存在数据匹配则删除行?即在程序结束后,file.txt应该看起来像

Istanbul
Moscow
Saint Petersburg
Berlin
Madrid
Kiev
Rome

由于Paris和London都存在于database.xml中的 city 节点内,因此它们将从file.txt中删除。 这样做的最快方法是什么?

3 个答案:

答案 0 :(得分:2)

使用System.IO.File.ReadAllLines()读取字符串数组中的所有文本文件条目。将XML加载到XElement。然后使用LINQ查找不在XElement子元素中的数组元素。我也可以发布代码,但它应该很简单。

修改

这应该基本上适合你:

var FileEntries = System.IO.File.ReadAllLines("TEXT_FILE_PATH");
var XMLEntries = XElement.Load("XML_FILE_PATH").Elements().Select(xx => xx.Value);
var list = FileEntries.Where(e => !XMLEntries.Contains(e));

答案 1 :(得分:0)

以下是您需要的代码。

  • 为城市列表创建一个类,并将database.xml文件反序列化为对象
  • 逐行读取file.txt并检查每行以及从database.xml读取的城市列表
  • 如果城市名称未包含在城市列表中,请将其附加到字符串构建器
  • 将dtring构建器内容写入file.txt

    使用System.IO; 使用System.Linq; 使用System.Text; 使用System.Xml.Serialization;

    命名空间ConsoleApplication1 {     课程     {         static void Main(string [] args)         {             StringBuilder sb = new StringBuilder();

            CityList cityList = new CityList();
            XmlSerializer serializer = new XmlSerializer(typeof(CityList));
            using (FileStream fileStream = new FileStream("database.txt", FileMode.Open))
            {
                cityList = (CityList)serializer.Deserialize(fileStream);
            }
    
            using (StreamReader file = new StreamReader("file.txt"))
            {
                string line;
                while ((line = file.ReadLine()) != null)
                {
                    if (!cityList.cities.Any(line.Contains))
                        sb.AppendLine(line);
                }
            }
    
            File.WriteAllText("file.txt", sb.ToString());
        }
    }
    
    
    [XmlRoot("city-group")]
    public class CityList
    {
        [XmlElement("city")]
        public string[] cities { get; set; }
    }
    

    }

答案 2 :(得分:0)

这是完整的解决方案

[XmlRoot("city-group")]
public class Citites
{
    [XmlElement("city")]
    public string[] City { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        // 1. read all city's names from xml file
        Citites cities;
        using (StreamReader reader = new StreamReader("database.xml"))
        {
            var xs = new XmlSerializer(typeof(Citites));
            cities = (Citites)xs.Deserialize(reader);

        }
        // 2. read current file and open temp file for insert not matched city 
        string tempFile = Path.GetTempFileName();
        using (StreamReader rw = new StreamReader("file.txt"))
        using (var sw = new StreamWriter(tempFile))
        {
            {
                // while of not end
                while (rw.Peek() > 0)
                {
                    // read next line
                    string city = rw.ReadLine();
                    if (!cities.City.Contains(city))
                    { 
                        // the city's name no matched, insert to temp file
                        sw.WriteLine(city);
                    }
                }
            }
        }
        // 3. replace the current file with a temp file
        File.Delete("file.txt");
        File.Move(tempFile, "file.txt");
    }
}

如果 file.txt 非常大,那么立即读取所有行是一个错误的决定。这将加载RAM
在这个解决方案中,我们逐行阅读而不是加载整个文件的内容。