正确选择文件流对象
应用程序使用RapidXML来编辑XML文件。编辑不是自动的,并且偶尔会发生:XML 内容显示在 GUI 中,并且用户执行一些更改 XML 的操作。每个更改都必须立即保存到磁盘。
加载 RapidXML 文档对象需要将文件内容复制到字符串中。文档中的每次更改都会将文档对象的内容复制回文件中。
在此示例中,文件同时用于输入和输出。 在这种情况下,是否应将单个 std::fstream
对象用于所有输入/输出操作?它会在应用程序启动时打开一次,用于输入/输出,并在应用程序结束时关闭。
或者,每当需要执行文件输入/输出时,应使用 std::ifstream
和 std::ofstream
的本地(临时)实例 ?例如 std::ifstream
在开头用于读取文件(打开、读取、关闭);类似地,每当必须将 DOM 导出到文件(打开、写入、关闭)时,就会使用 std::ofstream 实例。
我不关心这里的性能(由于应用程序的性质),但很好奇在这种情况下文件流对象的正确选择。
Application uses RapidXML to edit XML file. Editing is not automated and takes place occasionally: XML content is displayed in GUI and user performs some actions which change XML. Each change must be saved to disk immediately.
Loading RapidXML document object requires copying the content of the file into a string. Each change in a document is followed by copying the content of the document object back into the file.
File is used both for input and output in this example. Shall a single std::fstream
object be used for all input/output operations in this case? It would be opened once, at the application startup, used for input/output, and closed at the end of the application.
Or, shall local (temporary) instances of std::ifstream
and std::ofstream
be used whenever file input/output needs to be performed? E.g. std::ifstream
to be used at the beginning for reading the file (open, read, close); similarly, std::ofstream
instance to be used whenever DOM must be exported into the file (open, write, close).
I am not concerned about performances here (due to the nature of the application) but am curious about the proper choice of file stream objects in this case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当要重写的数据量与原始数据不同时,就地编辑文件是一件非常痛苦的事情。如果您的文件格式要求数据连续并且没有漏洞语法,那么您实际上别无选择,只能重写文件(至少从修改位置的开头开始) 。
此外,还有其他限制。如果您需要在继续之前将数据刷新到磁盘,那么您也许可以使用单个
std::fstream
进行多次编辑。即使您在文件流上调用flush()
方法,操作系统通常也不会将文件刷新到磁盘。有些平台提供非便携式解决方案来真正强制写入。因此,如果您需要将其刷新到磁盘,最好的选择是实际关闭该文件。因此,特别是对于关键应用程序,我建议使用第二种方法(初始加载时的
ifstream
,每次写入时的ofstream
)。我还建议写入临时文件,然后将完整的重写移动到首选位置,替换原始文件。这可以确保您不会丢失任何数据(至少在提供原子文件移动的系统上)。Editing files in place when the amount of data to re-write is different from the original data is a real pain. If your file format requires data to be sequential and has no syntax for holes, then you don't really have a choice but to re-write the file (at least from the start of the modified position).
Also, there are additional constraints. If you require the data to be flushed to disk before continuing, then you might be able to use a single
std::fstream
for multiple edits. Operating systems typically don't flush the file to disk even when you invoke theflush()
method on file streams. Some platforms offer non-portable solutions to really force a write. So if you need it to be flushed to disk, your best bet is to actually close the file.Thus, especially for critical applications, I would recommend the 2nd approach (
ifstream
at initial load,ofstream
at each write). I would also recommend writing to a temporary file, then moving the complete re-write to the preferred location, replacing the original files. This ensures you won't have any data loss (at least on systems that offer atomic file move).我绝对喜欢
std::ifstream
的本地临时实例和std::ofstream
。我什至不确定它是否会以其他方式工作;开一个std::ofstream
清空现有文件的内容。只是寻求到开头并且覆盖不会删除任何以前的内容,
如果更改的结果缩短了文件,您仍然会留下
带有早期内容中剩余的字符。
I'd definitely favor local temporary instances of
std::ifstream
andstd::ofstream
. I'm not even sure it would work otherwise; opening anstd::ofstream
empties the contents of an existing file. Just seekingto the beginning and overwriting doesn't remove any previous contents,
and if the results of the changes shorten the file, you'll still be left
with leftover characters from the earlier contents.