[英]How to write an object to file in C++
我有一個帶有幾個文本字符串作為成員的對象。 我想一次性將這個對象寫入文件,而不是將每個字符串寫入文件。 我怎樣才能做到這一點?
您可以覆蓋operator>>
和operator<<
以讀取/寫入流。
帶有一些值的示例Entry struct
:
struct Entry2
{
string original;
string currency;
Entry2() {}
Entry2(string& in);
Entry2(string& original, string& currency)
: original(original), currency(currency)
{}
};
istream& operator>>(istream& is, Entry2& en);
ostream& operator<<(ostream& os, const Entry2& en);
執行:
using namespace std;
istream& operator>>(istream& is, Entry2& en)
{
is >> en.original;
is >> en.currency;
return is;
}
ostream& operator<<(ostream& os, const Entry2& en)
{
os << en.original << " " << en.currency;
return os;
}
然后打開文件流,並為您調用的每個對象:
ifstream in(filename.c_str());
Entry2 e;
in >> e;
//if you want to use read:
//in.read(reinterpret_cast<const char*>(&e),sizeof(e));
in.close();
或輸出:
Entry2 e;
// set values in e
ofstream out(filename.c_str());
out << e;
out.close();
或者,如果您想使用流read
和write
那么您只需替換operator
實現中的相關代碼。
當變量在struct / class中是私有的時,你需要將operator
s聲明為friend方法。
您可以實現任何您喜歡的格式/分隔符。 當你的字符串包含空格時,使用getline()接受字符串和流而不是>>
因為operator>>
默認使用空格作為分隔符。 取決於你的分隔符。
它被稱為序列化。 SO上有許多序列化線程。
boost中還包含一個很好的序列化庫。
http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/index.html
基本上你可以做到
myFile<<myObject
和
myFile>>myObject
與boost序列化。
如果你有:
struct A {
char a[30], b[25], c[15];
int x;
}
然后你可以用write(fh,ptr,sizeof(struct a))來編寫它。
當然,這不是可移植的(因為我們沒有保存“int”的結尾或大小,但這對你來說可能不是問題。
如果你有:
struct A {
char *a, *b, *c;
int d;
}
然后你不打算寫這個對象; 你想要序列化它。 最好的辦法是查看Boost庫並使用它們的序列化例程,因為在沒有反射的語言中它不是一個簡單的問題。
實際上並不是一種簡單的方法,它畢竟是C ++,而不是PHP或JavaScript。
http://www.parashift.com/c++-faq-lite/serialization.html
Boost還有一些庫: http : //www.boost.org/doc/libs/release/libs/serialization ...就像Tronic已經提到過:)
更好的方法是單獨編寫每個字段以及字符串長度。
作為替代方法,您可以創建一個char
數組(或std::vector<char>
)並將所有成員寫入緩沖區,然后將緩沖區寫入輸出。
潛在的棘手是允許編譯器在類或結構中的成員之間插入填充。 使用memcpy
或std::copy
將導致填充字節寫入輸出。
請記住,您需要編寫字符串長度和內容或內容后跟一些終止字符。
其他人會建議查看Boost序列化庫。
不幸的是,這通常不太可能。 如果您的結構只包含純數據(沒有指針或復雜對象),您可以將它存儲為一個塊,但如果可移植性是一個問題,必須小心。 填充,數據類型大小和endianess問題使這成為問題。
您可以使用Boost.Serialization來最小化正確的可移植和可版本化的searialization所需的代碼量。
假設您的目標如上所述,只需調用write()或fwrite()或其他任何東西來寫出對象,您首先需要將字符串和其他對象數據復制到單個連續的內存塊中。 然后你可以通過一次調用寫出()該內存塊。 或者,如果您的平台上有該調用,則可以通過調用writev()來執行向量寫入。
也就是說,通過減少寫入調用次數,您可能不會獲得太多收益。 特別是如果你已經使用fwrite()或類似的,那么C庫已經為你做了緩沖,所以無論如何多個小調用的成本是最小的。 不要讓自己經歷許多額外的痛苦和代碼復雜性,除非它實際上會做一些好事......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.