如何优化我的C# WinForms代码,以便有效地将大型XML文件拆分为较小的文件?

xjreopfe  于 2023-06-06  发布在  C#
关注(0)|答案(1)|浏览(118)

我有一个很大的.XML文件,有8 mil个节点(大约1GB)。目前我使用XML阅读器读取文件和XML写入器写入新的。XML文件的文件。目前我注意到速度非常不一致。如果我每个文件创建800000个节点,大约需要10分钟,如果我说每个文件创建80000个节点,则需要15-20分钟,因此由于某种原因,创建的文件越多,所需的时间就越长。
XML文件:

<CNJExport>
<Item>
<ID>1</ID>
<name>Logitech MX Master 3 mouse</name>
<price>423.36</price>
</Item>
</CNJExport>

当前代码:此部分为不做文件、不写文件的代码

public string XML_file_path;
        
BackgroundWorker bw;

public Form1()
{
    InitializeComponent();
}

private void AppendText(string text)
{
    if (Progress_output_text.InvokeRequired)
    {
        Progress_output_text.Invoke(new Action<string>(AppendText), text);
    }
    else
    {
        Progress_output_text.AppendText(text);
    }
}

private async void button1_Click(object sender, EventArgs e)
{
    Generate_Button.Enabled = false;

    // Start the background worker
    bw = new BackgroundWorker();
    bw.DoWork += (obj, ea) => TasksAsync(1);
    bw.RunWorkerCompleted += (obj, ea) => Generate_Button.Enabled = true; // Enable the button after the operation completes
    bw.RunWorkerAsync();
}

private async void TasksAsync(int times)
{
    string Error_code_save = "", file_name_and_type = File_Path_Textbox.Text.Substring(File_Path_Textbox.Text.LastIndexOf('\\') + 1), full_file_path, file_name;
    int number_is_not_devisable = 0, total_items_in_XML = 0, Current_item_line = 0, filesCreated = 0, total_files_at_end;

    XML_file_path = File_Path_Textbox.Text;

    if (Number_Of_Elements_Per_file.Value == 0)
    {
        Error_code_save += "ERROR: Number of XML files cannot be zero\r";
    }
    else if (!string.IsNullOrEmpty(Error_code_save))
    {
        Progress_output_text.Invoke((MethodInvoker)delegate
        {
            Progress_output_text.Text += "You set " + Number_Of_Elements_Per_file.Value + " items per file\r";
        });
    }

    if (string.IsNullOrEmpty(File_Path_Textbox.Text) || string.IsNullOrEmpty(File_Destination_Textbox.Text))
    {
        Error_code_save += "ERROR: Path and/or Destination have not been set, please set them and generate again";
    }

    if (!string.IsNullOrEmpty(Error_code_save))
    {
        MessageBox.Show(Error_code_save);
        return;
    }

    file_name = file_name_and_type.Substring(0, file_name_and_type.Length - 4);

    using (XmlReader reader = XmlReader.Create(XML_file_path))
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element && reader.Name == "Item")
                total_items_in_XML++;
        }
    }

    if (total_items_in_XML % Number_Of_Elements_Per_file.Value > 0)
    {
        number_is_not_devisable = 1;
    }

    total_files_at_end = (int)Math.Ceiling(total_items_in_XML / Number_Of_Elements_Per_file.Value);

    for (int i = 1; i <= total_files_at_end; i++)
    {
        int progressValue = (int)(i * 100.0 / total_files_at_end);

        progressBar1.Invoke((MethodInvoker)delegate
        {
            progressBar1.Value = progressValue;
        });

        full_file_path = string.Concat(File_Destination_Textbox.Text, '\\', file_name, i, ".xml");
        try
        {
            create_file(full_file_path, Current_item_line);

            filesCreated++;

            // Reset the progress bar after creating 10 files
            if (filesCreated % 10 == 0)
            {
                await Task.Delay(2000); // Wait for 2 seconds
                progressBar1.Invoke((MethodInvoker)delegate
                {
                    progressBar1.Value = 0;
                });
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("An error occurred while creating the file: " + ex.Message);
        }

        Current_item_line += (int)Number_Of_Elements_Per_file.Value;
    }

    Progress_output_text.Invoke((MethodInvoker)delegate
    {
        Progress_output_text.Text += filesCreated + " files have been created in " + File_Destination_Textbox.Text + "\r\n";
    });
}

这部分是实际的创建文件函数

public void create_file(string full_file_path, int Current_item_line)
{
    using (XmlWriter writer = XmlWriter.Create(full_file_path))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("CNJExport");

        using (XmlReader reader = XmlReader.Create(XML_file_path))
        {
            int itemCounter = 0;
            // Loop through the XML file and copy selected items to the new file
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "Item")
                {
                    if (itemCounter >= Current_item_line && itemCounter < Current_item_line + Number_Of_Elements_Per_file.Value)
                    {
                        writer.WriteNode(reader, true);
                    }
                    itemCounter++;
                }
            }
        }

        writer.WriteEndElement();
        writer.WriteEndDocument();
    }
}
wfveoks0

wfveoks01#

这段代码稍微高效一点

public void create_file(string full_file_path, int Current_item_line)
        {
            using (XmlWriter writer = XmlWriter.Create(full_file_path))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("CNJExport");

                using (XmlReader reader = XmlReader.Create(XML_file_path))
                {
                    int itemCounter = 0;
                    // Loop through the XML file and copy selected items to the new file
                    while (!reader.EOF)
                    {
                        if (reader.Name != "Item")
                        {
                            reader.ReadToFollowing("Item");
                        }
                        if (!reader.EOF)
                        {
                           if (itemCounter >= Current_item_line && itemCounter < Current_item_line + Number_Of_Elements_Per_file.Value)
                           {
                               writer.WriteNode(reader, true);
                           }
                        }
                        itemCounter++;
                    }
                }
                writer.WriteEndElement();
                writer.WriteEndDocument();

            }
        }

相关问题