我有一个进程可以获取一系列"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)
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(字节顺序标记)的代码。
我看不到这方面有任何真正的改进......这有点令人失望。由于无法“移动”文件,因此您始终必须移动整个文件中的字节才能在顶部注入任何内容。
您可能会发现使用原始流而不是必须将流实际解析为文本的 StreamReader 会带来一些性能优势。
归档时间: |
|
查看次数: |
10600 次 |
最近记录: |