向文件写入更多内容,而不仅仅是纯文本

Writing more to a file than just plain text

提问人:Joe Fontana 提问时间:9/17/2008 最后编辑:Joe Fontana 更新时间:4/8/2014 访问量:628

问:

我一直能够用 C++ 读取和写入基本的文本文件,但到目前为止,还没有人讨论过更多。

我的问题是这样的:

如果我自己开发一种文件类型供我创建的应用程序使用,我将如何将数据写入文件并保留布局、格式等?是否有任何标准,或者它只是取决于程序员的创造力?

文件

评论


答:

0赞 Vhaerun 9/17/2008 #1

如果创建一个二进制文件,则可以将任何文件写入其中。唯一的缺点是你必须确切地知道它从哪里开始,从哪里结束。

0赞 Frank Wiles 9/17/2008 #2

您通常使用第三方库来完成这些操作。例如,您可以链接 Oracle 的数据库库,以便与数据库通信。由于底层文件类型(即 Excel 电子表格与 Openoffice、Oracle 与 MySQL 等)不同,因此这些库抽象出您无需关心文件的构造方式。

希望能帮助你找到你要找的东西!

2赞 cazlab 9/17/2008 #3

当然,有许多标准。可能使用的是某种风格的 xml,因为已经存在一些库和工具来帮助您使用它,但没有什么能阻止您发明自己的。

3赞 David Thibault 9/17/2008 #4

您基本上必须提出自己的文件格式并编写二进制数据。 还可以序列化对象模型并将输出写入文件,但这通常效率较低。

最好使用现有数据库,或者使用 xml(或其他)来满足简单需求。如果要以已存在的格式编写文件,请查找支持该格式的库。

评论

0赞 jmucchiello 12/20/2008
不要序列化对象模型。只需对对象模型进行一次更改,即可读取旧的格式化文件。
2赞 Marc Gear 9/17/2008 #5

好吧,您可以以可以读取的格式存储数据,但可以保持数据的完整性(例如XML或JSON)。

或者(不寒而栗)你可以想出你自己的专有二进制格式,并使用它。

2赞 Jean 9/17/2008 #6

你会像处理文本文件一样处理它。逐字节写入数据,以这样一种方式进行编码,即当您读取文件时,您知道您正在读取的内容。 对于电子表格应用程序,您甚至可以使用文本格式(OOXML、OpenDocument)来存储演示文稿和内容信息。

或者,您可以定义二进制数据结构并将其直接写入文件。

文本或二进制格式之间的选择取决于应用程序。对于配置文件,您可能更喜欢可以在应用程序外部修改的文本文件,对于数据库,出于性能原因,您很可能会选择二进制格式。

3赞 Tom Ritter 9/17/2008 #7

您必须知道您尝试创建的文件的二进制文件格式。考虑一下 Joel 关于这个主题的帖子:97-2003 文件格式是一个 349 页的规范。

几乎在所有时候,要做这样的事情,你都会使用一个API,以避免繁重的工作。但是要小心,因为反复试验和通过反复试验找出“什么有效”可能会导致程序升级破坏您的代码。另外,您必须考虑其他操作系统、次要版本差异、补丁等。

1赞 Brian R. Bondy 9/17/2008 #8

有关各种文件类型的文件格式的信息,请参阅 wotsit.org。示例:您可以确切地弄清楚如何写出 .BMP 文件以及如何编写它。

写入数据库可以通过使用您的语言中的包装类来完成,主要是向它传递 SQL 命令。

0赞 Nerdfest 9/17/2008 #9

使用 xml(开放、描述性和可验证的东西),并坚持使用文本。这种事情也有标准,包括 ODF

0赞 foxxtrot 9/17/2008 #10

您可以以二进制文件的形式打开文件,而不是文本(如何做到这一点在某种程度上取决于平台),从那里您可以将数据直接写入磁盘。唯一真正需要注意的是 endianess,当将文件从一个架构移动到另一个架构(例如,x86 到 PPC)时,这可能会成为一个问题。

将二进制数据写入磁盘实际上并不比编写文本难,实际上,您的创造力是您存储数据的关键。

0赞 Allan Wind 9/17/2008 #11

一般问题通常称为应用程序状态的序列化,在您的情况下,使用对您有意义的任何格式的文件的源/目标。如今,首选的输入/输出格式是 XML,您可能需要查看此字段中的现有标准。那么问题就变成了如何从我的系统状态映射到特定的架构。Boost 有一个序列化框架,你可能想看看。

/艾伦

0赞 Eclipse 9/17/2008 #12

您可以采用多种方法,但通常需要某种序列化库。BOOST::Serialization 或 Google 的 Protocal Buffers 就是一个很好的例子。基本思想是,您有表示数据的内存结构(类和对象),并且希望以可用于再次重构这些结构的方式将该数据写入文件。

如果你对使用库犹豫不决,你可以手动完成这一切,但要意识到你最终可能会编写大量冗余代码,或者开发自己的库。请参阅 fopen、fread、fwrite 和 fclose 了解起点。

0赞 user21826 12/20/2008 #13

自定义数据的典型二进制文件格式是“索引文件格式”,包括

-------
|index|
-------
|data |
-------

索引包含“指向”数据的记录。

索引由包含偏移量和大小的记录组成。偏移量告诉您数据在文件中的存储位置,大小告诉您在该偏移量处的数据大小(即要读取的字节数)。

typedef struct {
  size_t offset
  size_t size
} Index

typedef struct {
  int  ID
  char First[20]
  char Last[20]
  char *RandomInfo
} Data

假设要在文件中存储 50 条记录,则将创建 50 个索引和 50 个数据结构。50 个索引结构将首先写入文件,然后是 50 个数据结构。

要读取要读取 50 个索引结构中的文件,然后从读入索引结构中的数据中,您可以知道在哪里“查找”读取数据记录。

查找 (fopen, fread, fwrite, fclose, ftell) 以获取用于读取/写入数据的函数。

(对不起,我的分号键不起作用)

0赞 icedwater 4/8/2014 #14

1985年打来电话,说他们有一些帮助,你愿意读一读。交换文件格式至今仍在使用,并提供了一些围绕二进制文件的基本元数据,例如 RIFF 或 WAV 音频。(不幸的是,TIFF是一个虚假的朋友。据称它甚至启发了巴布亚新几内亚,所以它不会那么糟糕。