就地修改 XML 文件?

发布于 2024-12-10 05:23:28 字数 313 浏览 1 评论 0原文

假设我有以下 XML 文件:

<book>
 <name>sometext</name>
 <name>sometext</name>
 <name>sometext</name>
 <name>Dometext</name>
 <name>sometext</name>
</book> 

如果我想通过将 D 更改为 s 来修改内容(如第四个“name”节点所示),而不必读/写整个文件,这可能吗?

Suppose I have the following XML File:

<book>
 <name>sometext</name>
 <name>sometext</name>
 <name>sometext</name>
 <name>Dometext</name>
 <name>sometext</name>
</book> 

If I wanted to modify the content by changing D to s (As shown in the fourth "name" node) without having to read/write the entire file, would this be possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月光色 2024-12-17 05:23:28

10 MB 的文件不是问题。把它吸起来。修改 DOM。将其写回文件系统。 10 GB 更是一个问题。在这种情况下:

假设:您没有更改文件的长度。将文件视为字符数组而不是字符(链接)列表:您不能在中间添加字符,只能更改它们。

您需要寻找文件中要更改的位置,然后将该字符写入到磁盘。

在 .NET 世界中,使用 FileStream 对象,您可以将 Position 属性设置为 D 字符的索引,然后编写一个单个 s 字符。 查看这个有关文​​本文件随机访问的问题。

另请阅读此问题:如何使用 C# 将字符插入文件。看起来您无法真正使用 FileStream 对象,而必须求助于写入单个字节。

祝你好运。但实际上,如果我们只谈论 10 MB,那么就将其吞掉吧。计算机应该完成你的工作。

A 10 MB file is not a problem. Slurp it up. Modify the DOM. Write it back to the filesystem. 10 GB is more of a problem. In that case:

Assumption: You are not changing the length of the file. Think of the file as an array of characters and not a (linked) list of characters: You cannot add characters in the middle, only change them.

You need to seek the position in the file to change and then write that character to disk.

In the .NET world, with a FileStream object, you what to set the Position attribute to the index of the D character and then write a single s character. Check out this question on random access of text files.

Also read this question: How to insert characters to a file using C#. It looks like you can't really use the FileStream object, but instead will have to resort to writing individual bytes.

Good luck. But really, if we are only talking 10 MB, then just slurp it up. The computer should be doing your work.

飘逸的'云 2024-12-17 05:23:28

我只需读入文件,进行处理,然后将其吐出。

这可以通过 XmlReader 以流式传输方式完成 - - 它比 XmlDocument 或 XDocument 需要更多的手动工作,但它确实避免了创建内存中 DOM(XmlDocument/XDocument 可以与相同的读/写模式一起使用,但通常需要完全重建内存中):

  1. 打开文件输入文件流 (XmlReader)
  2. 打开输出文件流(XmlWriter,到不同的文件
  3. 从 XmlReader 读取并写入 XmlWriter,根据需要执行任何转换。
  4. 关闭流
  5. 将新文件移动到旧文件(覆盖,原子操作)

虽然这可以设置为通过一堆非常聪明的工作来处理同一打开文件上的输入和输出 > 不会保存任何内容,并且存在许多边缘情况,包括随着文件长度的减小而增加。事实上,尝试简单地向后移动文件内容以填补空白或向前移动文件内容以腾出新空间可能会更慢。除了最基本的长度保留操作之外,文件系统缓存可能会使任何“收益”最小化/毫无意义。此外,就地修改文件不是原子操作,并且在发生错误时通常是不可恢复的:以临时文件为代价,读/写/移动方法是原子操作最终文件内容。

或者,考虑 XSLT —— 它就是为此而设计的;-)

快乐编码。

I would just read in the file, process, and spit it back out.

This can be done in a streaming fashion with XmlReader -- it's more manual work than XmlDocument or XDocument, but it does avoid creating an in-memory DOM (XmlDocument/XDocument can be used with this same read/write pattern, but generally require the full reconstruction in-memory):

  1. Open file input file stream (XmlReader)
  2. Open output file stream (XmlWriter, to a different file)
  3. Read from XmlReader and write to XmlWriter performing any transformations as neccessary.
  4. Close streams
  5. Move new file to old file (overwrite, an atomic action)

While this can be setup to process input and output on the same open file with a bunch of really clever work nothing will be saved and there any many edge cases including increasing on decreasing file lengths. In fact, it might be slower to try and simply shift the contents of a file backwards to fill in gaps or shift the file contents forward to make new room. The filesystem cache will likely make any "gains" minimal/moot for anything but the most basic length-preserving operation. In addition, modifying a file in place is not an atomic action and is generally non-recoverable in case of an error: at the expense of a temporary file, the read/write/move approach is atomic wrt the final file contents.

Or, consider XSLT -- it was designed for this ;-)

Happy coding.

回心转意 2024-12-17 05:23:28

最干净(也是最好)的方法是使用 XmlDocument 对象进行操作,但快速但肮脏的解决方案是将 XML 读取为字符串,然后:

xmlText = xmlText.Replace("Dometext", "sometext");

The cleanest (and best) way would be to use the XmlDocument object to manipulate, but a quick and dirty solution is to just read the XML to a string and then:

xmlText = xmlText.Replace("Dometext", "sometext");
冷情妓 2024-12-17 05:23:28

XML 文件是文本文件,不允许插入/删除。唯一支持的突变是 OverWrite 和 Append。与 XML 不太匹配。

因此,首先请确保您确实需要这个。这是一个复杂的操作,只有在非常大的文件上才值得这样做。

由于长度可能会发生变化,因此您至少必须在第一次更换后移动所有内容。多次替换的可能性意味着您可能需要一个大的缓冲区来适应更改。

复制整个文件更容易。这对于 I/O 来说是昂贵的,但可以节省内存使用。

An XML file is a text file and does not allow for insertion/deletions. The only mutations supported are OverWrite and Append. Not a good match for XML.

So, first make very sure you really need this. It's a complicated operation, only worth it on very large files.

Since there could be a change in length you will at least have to move everything after the first replacement. The possibility of multiple replacements means you may need a big buffer to accommodate the changes.

It's easier to copy the whole file. That is expensive in I/O but you save on memory use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文