合并两个文件并处理重复的条目

时间:2013-09-09 12:02:39

标签: c# file io merge

编辑2:如果您希望获得更多代码,请告诉我们。但是,我真的不知道你想要的其他代码,因为问题显然在于下面的代码(不是我的编辑)。

编辑:如果有人仍然对这个问题的答案感兴趣,我还没有完全弄清楚,但发现了一些相当奇怪的东西。在我看来List[index].Replace(oldValue, newValue);(一般格式)对我来说不起作用!这是我问题的最后一部分所在。我已经添加了断点并逐步调试了我的应用程序,当卡片已经存在时检查newFile是否确实包含lines[i](newsflash,它确实如此)但是命令仍然不想工作! Replace();几乎没用。这是为什么?我的代码有问题吗?天哪,我甚至打破了这个片段:

newFile[newFile.IndexOf(lines[i])].Replace(lines[i],
                                       string.Format(
                                       "{0}|{1}", title, int.Parse(times) + int.Parse(secondTimes)));

更简单(仅用于评估目的,看看元素是否实际被替换,当i == 0时,Winged Dragon是newFile的第一个(数字0)元素,请注意):

newFile[0].Replace("Winged Dragon, Guardian of the Fortress #1|3", "Just replace it with this dammit!");

但它仍然拒绝工作!顺便说一句,对不起咆哮,但我不能,因为我的生活,明白我在这里做错了什么。


昨天我问了一个类似的问题(可以在这里找到:Writing to a file and handling duplicate entries),我得到了我想要的答案。但是,现在我想扩展该功能,允许我的应用程序将两个文件合并为一个,同时考虑重复的条目。同样,所有给定文件的每一行的一般格式为string.Format("{0}|{1}", TitleOfCard, NumberOfTimesCardIsOwned);

在我开始使用代码之前,您可能想知道我让用户通过 OpenFileDialog(Multiselect = True)浏览要合并的文件。

现在,这是我的代码:

   private void btnMerge_Click(object sender, EventArgs e)  
   {     
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {   
            // Save file names to array.
            string[] fileNames = openFileDialog1.FileNames;

            // Loop through the files.
            foreach (string fileName in fileNames) 
            {
                // Save all lines of the current file to an array.
                string[] lines = File.ReadAllLines(fileName);

                // Loop through the lines of the file.
                for (int i = 0; i < lines.Length; i++)
                {
                    // Split current line ( remember, all lines are of format {0}|{1} ).
                    string[] split = lines[i].Split('|');
                    string title = split[0]; //
                                             // = TitleOfCard, NumberOfTimesCardIsOwned
                    string times = split[1]; //

                    // newFile is a list that stores the lines from the default resources file.
                    // If it contains the current line of the file that we're currently looping through...
                    if (newFile.Contains(lines[i]))
                    {
                        // Split the line once again.
                        string[] secondSplit = newFile.ElementAt(
                            newFile.IndexOf(lines[i])).Split('|');
                        string secondTitle = secondSplit[0];
                        string secondTimes = secondSplit[1];

                        // Replace the newFile element at the specified index with:
                        // - Same title
                        // - Add the 'times' of the newFile element and the 'times' of the newFile
                        // => KEEP TITLE, UPDATE THE NUMBER OF TIMES CARD IS OWNED
                        newFile[newFile.IndexOf(lines[i])].Replace(lines[i],
                                       string.Format(
                                       "{0}|{1}", title, int.Parse(times) + int.Parse(secondTimes)));
                    }
                    // If newFile does not contain the current line of the file we're looping through, just add it to newFile.
                    else
                        newFile.Add(string.Format(
                                        "{0}|{1}",
                                        title, times));
                }
            }

            // Overwrite resources file with newFile.
            using (StreamWriter sw = new StreamWriter("CardResources.ygodc"))
            {
                foreach (string line in newFile)
                    sw.WriteLine(line);
            }

            // Clear listview and reupdate it vv
            lvResources.Clear();

            string[] originalFile = File.ReadAllLines("CardResources.ygodc");

            foreach (string line in originalFile)
            {
                string[] split = line.Split('|');
                string title = split[0];
                string times = split[1];

                ListViewItem lvi = new ListViewItem(title);
                lvi.SubItems.Add(times);
                lvResources.Items.Add(lvi);
            }
        }
    }

当我尝试合并文件时,我遇到问题的行是string times = split[1];,因为 IndexOutOfRangeException 会被抛出。你能帮我么?提前谢谢。

1 个答案:

答案 0 :(得分:0)

您很可能正在尝试处理空行。

忽略空行:

if (lines[i].Trim() == string.Empty) 
    continue;

string[] split = lines[i].Split('|');
if (split.Length != 2)
    throw new InvalidOperationException("invalid file");
string title = split[0];
string times = split[1];

忽略无效行:

string[] split = lines[i].Split('|');
if (split.Length != 2) 
    continue;
string title = split[0];
string times = split[1];