我需要一种方法来写的三种不同结构的二进制文件,后来不得不进行搜索。 (如在,例如,结构A具有两个字段,一个int和炭;结构B具有int和一个长;我需要输出,其INT等于从键盘给出的所有结构)。
我知道如何写同一种结构的文件,以及如何对其进行搜索,但在这里,我只是输了,最好的事情我想出的声明包含所有可能需要的字段的结构和离开我不需要的那些空的,但它真的感觉错了,必须有一个更好的方式来做到这一点。
我读过有关二进制文件,无法找到任何有关大多数例子和教程处理写一个数据类型。 任何人都可以点我在正确的方向?
编辑:我在寻找什么@Jerry_coffin称为数据库模式,可能会使用现有的数据库系统之一是,最好的办法去,大概。 谢谢大家的建议
有两种基本的方法来处理你的数据(你有没有说过它适用):
- 我认为的字处理器型号:读取,使用的文件/根据需要修改数据,当用户保存所有的数据写回(也许自动,即使用户没有明确要求保存)。
- 我认为作为一个数据库模式:你通常不打算读取整个文件到内存中一次。 可以根据需要更新文件的碎片和零件。 您结构,以支持更多或更少的随机存取文件。
如果你在第一个计划,事情很简单。 保持你的三种结构分开在内存中。 当你把它们写出来,你写的所有的一种类型的,那么所有的未来,最后所有的三分之一。 你需要足够的元数据的地方,以便能够读取数据回到正常。
如果你在第二个计划,它可能更复杂。 你必须沿着这条线的几个不同的可能性:
- 将数据分成三个独立的文件,并分别搜索每一个。 我知道你说你需要一个单一的文件,但如果你能做到这一点,它可能是最干净的方法。
- 在你的源代码,创建了三种类型的联合,连同现场告诉其余的是哪种类型的。 这基本上只是留下一个特定结构的空不必要的空间,但是使它稍微简单的外部和内部表示之间的映射。
- 建立更接近于一个完全成熟的数据库系统。 基本上,你要生记录写入到文件中。 然后,你会需要某种指数的告诉每个记录的开始。 然后,你可能需要添加至少一个指数,以帮助快速方便地找到特定的记录。
- 使用现有的数据库系统。 SQLite的是一个显而易见的选择。 另外,这不是因为众所周知的是STXXL 。 很显然的是,SQLite的提供了一个SQL接口的数据,这使得它更容易地支持之类的即席查询等(如果需要)。 STXXL提供了类似于在标准库容器的接口,但与存储在磁盘上的数据。 这已经相当频繁的测试和优化; 它通常会采取相当多的努力,以配合其性能。
至于这是优选的:这取决于。 单独的文件可能是最简单的。 受到最小的变化给出了具体的要求,我可能会设计一个单一类型为2建议,如果我需要存储大量的数据,可能使用STXXL。 如果您可能需要查询都更加流畅,我可能会考虑SQLite的。 我会避免,除非你的需求是非常明确和不寻常的编写自己的数据库系统,让你看到最小的努力导致了供您使用的一个主要的性能提升的可能性很大。 坦率地说,我认为这是件不可思议的事,但。
我会建议使用的protobuf
假设你创建以下protobuf的消息,例如。
message binary_info
{
message struct_1
{
required int32 intValue = 1;
required string strValue = 2;
}
message struct_2
{
required int32 intValue = 1;
required uint64 ulongValue = 2;
}
message struct_3
{
required int32 intValue = 1;
required uint64 ulongValue = 2;
required string strValue = 3;
}
required struct_1 st1 = 1;
required struct_2 st2 = 2;
required struct_3 st3 = 3;
}
让谷歌的Protobuf创造必要的文件给你。 请参阅开发人员指南在https://developers.google.com/protocol-buffers/docs/overview
(在我的例子,protoc具有自动生成message.pb.h和message.pb.cc在通讯文件/原/ *)
然后,您可以编写一个程序将数据从文件保存和读取/
/*
* main.cpp
*
* Created on: 30/05/2014
* Author: ankit
*/
#include "communications/proto/message.pb.h"
#include <iostream>
#include <fstream>
using namespace std;
bool write_data()
{
binary_info_struct_1* s1 = new binary_info_struct_1();
s1->set_intvalue(1);
s1->set_strvalue("string for s1");
binary_info_struct_2* s2 = new binary_info_struct_2();
s2->set_intvalue(2);
s2->set_ulongvalue(2000);
binary_info_struct_3* s3 = new binary_info_struct_3();
s3->set_intvalue(3);
s3->set_ulongvalue(3000);
s3->set_strvalue("string for s3");
binary_info b;
b.set_allocated_st1(s1);
b.set_allocated_st2(s2);
b.set_allocated_st3(s3);
if(!b.IsInitialized())
return false;
fstream output("myfile.data", ios::out | ios::binary);
b.SerializeToOstream(&output);
return true;
}
void read_data()
{
fstream input("myfile.data", ios::in | ios::binary);
binary_info b;
b.ParseFromIstream(&input);
cout << "struct 1, int data: " << b.st1().intvalue() << endl;
cout << "struct 1, string data: " << b.st1().strvalue() << endl;
cout << "struct 2, int data: " << b.st2().intvalue() << endl;
cout << "struct 2, ulong data: " << b.st2().ulongvalue() << endl;
cout << "struct 3, int data: " << b.st3().intvalue() << endl;
cout << "struct 3, ulong data: " << b.st3().ulongvalue() << endl;
cout << "struct 3, string data: " << b.st3().strvalue() << endl;
}
int main()
{
write_data();
read_data();
return 0;
}
希望这可以帮助!