在C#中将文本添加到文件的开头和结尾

ade*_*825 6 c# xml file-io

我有一个进程可以获取一系列"xml"文件.我把xml放在引号中的原因是文件中的文本没有一个根元素,它使得xml无效.在我的处理中,我想纠正这个并打开每个文件,在每个文件的开头和结尾添加一个根节点,然后将其关闭.这是我的想法,但这涉及打开文件,读取整个文件,在节点上标记,然后写出整个文件.这些文件的大小可能超过20 MB.

        foreach (FileInfo file in files)
        {
            //open the file
            StreamReader sr = new StreamReader(file.FullName);

            // add the opening and closing tags
            string text = "<root>" + sr.ReadToEnd() + "<root>";
            sr.Close();

            // now open the same file for writing
            StreamWriter sw = new StreamWriter(file.FullName, false);
            sw.Write(text);
            sw.Close();
        }
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Dan*_*ker 15

要避免将整个文件保存在内存中,请重命名原始文件,然后使用打开它StreamReader.然后打开原始文件名StreamWriter以创建新文件.

<root>前缀写入文件,然后将大量数据从读取器复制到写入器.当您传输了所有数据时,请写下结束</root>(如果您希望它是XML,请注意正斜杠).然后关闭这两个文件并删除重命名的原始文件.

char[] buffer = new char[10000];

string renamedFile = file.FullName + ".orig";
File.Move(file.FullName, renamedFile);

using (StreamReader sr = new StreamReader(renamedFile))
using (StreamWriter sw = new StreamWriter(file.FullName, false))
{
    sw.Write("<root>");

    int read;
    while ((read = sr.Read(buffer, 0, buffer.Length)) > 0)
        sw.Write(buffer, 0, read);

    sw.Write("</root>");
}

File.Delete(renamedFile);
Run Code Online (Sandbox Code Playgroud)


Guf*_*ffa 5

20 MB 并不是很多,但是当您将其作为字符串读取时,它将使用大约 40 MB 的内存。这也不是很多,但它是您不需要做的处理。您可以将其作为原始字节处理,以减少内存使用,并避免对数据进行解码和重新编码:

byte[] start = Encoding.UTF8.GetBytes("<root>");
byte[] ending = Encoding.UTF8.GetBytes("</root>");

byte[] data = File.ReadAllBytes(file.FullName);

int bom = (data[0] == 0xEF) ? 3 : 0;

using (FileStream s = File.Create(file.FullName)) {
   if (bom > 0) {
      s.Write(data, 0, bom);
   }
   s.Write(start, 0, start.Length);
   s.Write(data, bom, data.Length - bom);
   s.Write(ending, 0, ending.Length);
}
Run Code Online (Sandbox Code Playgroud)

如果您需要进一步减少内存使用量,请按照 Earwicker 的建议使用第二个文件。

编辑:
添加了处理 BOM(字节顺序标记)的代码。

  • “40 MB 内存......这也不是很多......”*咳嗽*。 (2认同)

Pau*_*der 3

我看不到这方面有任何真正的改进......这有点令人失望。由于无法“移动”文件,因此您始终必须移动整个文件中的字节才能在顶部注入任何内容。

您可能会发现使用原始流而不是必须将流实际解析为文本的 StreamReader 会带来一些性能优势。