在 C# 中将文本添加到文件的开头和结尾
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1008742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding text to beginning and end of file in C#
提问by adeel825
I have a process which picks up a series of "xml" files. The reason I put xml in quotes is that that the text in the file does not have a root element which makes in invalid xml. In my processing, I want to correct this and open up each file add a root node to the beginning and end of each file, and then close it up. Here is what I had in mind, but this involves opening the file, reading the entire file, tagging on the nodes, and then writing the entire file out. These files may be more than 20 MB in size.
我有一个获取一系列“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();
}
Any recommendations?
有什么建议吗?
回答by Paul Alexander
I can't see any real improvement on this...which is kind of a bummer. Since there's no way to "shift" a file you'll always have to move the bytes in the entire file to inject anything at the top.
我看不到任何真正的改进……这有点令人失望。由于无法“移动”文件,因此您必须始终移动整个文件中的字节以在顶部注入任何内容。
You may find some performance benefit by using raw streams rather than the StreamReader which has to actually parse the stream as text.
通过使用原始流而不是 StreamReader,您可能会发现一些性能优势,StreamReader 必须实际将流解析为文本。
回答by Daniel Earwicker
To avoid holding the whole file in memory, rename the original file, then open it with StreamReader
. Then open the original filename with StreamWriter
to create a new file.
为避免将整个文件保存在内存中,请重命名原始文件,然后使用StreamReader
. 然后打开原始文件名StreamWriter
以创建一个新文件。
Write the <root>
prefix to the file, then copy data in large-ish chunks from the reader to the writer. When you've transferred all the data, write the closing </root>
(note the forward slash if you want it to be XML). Then close both files and delete the renamed original.
将<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);
回答by Hyman Bolding
If you do not want to do this is C#, it would be easy to handle at the commandline or in a batch file.
如果您不想在 C# 中执行此操作,则可以在命令行或批处理文件中轻松处理。
ECHO ^<root^> > outfile.xml
TYPE temp.xml >> outfile.xml
ECHO ^</root^> >> outfile.xml
This would assume that you have some existing process for getting the data files that this could be hooked into.
这将假设您有一些现有的过程来获取可以连接到的数据文件。
回答by Guffa
20 MB is not terribly much, but when you read it as a string, it will use about 40 MB of memory. That's not terribly much either, but it's processing that you don't need to do. You can handle it as raw bytes to reduce the memory usage, and to avoid decoding and re-encoding the data:
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);
}
If you need to recude the memory usage much more, use a second file as Earwicker suggested.
如果您需要更多地减少内存使用量,请使用 Earwicker 建议的第二个文件。
Edit:
Added code to handle BOM (byte order mark).
编辑:
添加了处理 BOM(字节顺序标记)的代码。