簡體   English   中英

在文件中存儲std :: deque的二進制數據或字節,或從文件中檢索二進制數據或字節?

[英]Storing, retrieving binary data or bytes to and from a file for a std::deque?

我正在為游戲編寫“重播系統”,並且想知道如何存儲記錄的幀?

至於現在,我有以下代碼/結構(請注意:此代碼已縮短):

struct Point4D { float x, y, z, w; };
struct Point3D { float x, y, z; };
struct Point2D { float x, y; };
struct QuatRot { Point4D Front,Right,Up; };
struct VehicleInfo
{
    Point3D     Pos,Velocity,TurnSpeed;
    QuatRot     Rotation;
};
namespace Recorder
{
    struct FrameInfo
    //~380 bytes / frame| max 45600 bytes @ 120 fps
    //max 3.7 GB raw data for 24 hours of recording, not bad..
    {
        std::chrono::high_resolution_clock::duration time;
        VehicleInfo Vehicle;
        int Nitro;
        float RPM;
        int CurrentGear;
    };

    std::deque<FrameInfo> frames;
    FrameInfo g_Temp;

    void ProcessRecord()
    {
        //record vehicle data here to g_Temp
        frames.push_back(g_Temp);
        return;
    }
    //other recording code.......
};

我在想的是,制作一個字節的原始數組,將其分配給雙端隊列容器的大小,使用memcpy將它們從雙端隊列復制到數組,然后將所有數組字節寫入文件。

然后,如果我想讀取記錄數據,我只需讀取文件的字節並將其分配給新數組,然后使用memcpy將數組內容復制到雙端隊列。

這很像.. C.方式嗎? 必須采用其他方法將數據存儲在文件中,然后將其讀回雙端隊列(也許使用某些C ++ 11功能?)。

我將如何完成?

您推薦哪種方法?

如果這很重要,我正在使用Windows。

memcpy是過早的優化。

從磁盤讀取內容時,瓶頸是磁盤IO,而不是將其從內存的一部分復制到另一部分。

修復您的數據結構,使其使用固定大小的數據結構(而不​​是int ,使用32位int等)。

不要以二進制形式編寫std::chrono::high_resolution_clock::duration庫更新可以完全改變大小,而無需眨眼或流淚,更不用說它的含義了。 ms或其他形式寫出,因此含義始終保持不變(以64位整數表示)。 然后,您可以將其讀回到std::chrono::high_resolution_clock::duration

序列化時,請務必寫出版本號和結構大小,以便反序列化甚至可以處理基本的版本控制。

我會寫一個“到流”和“從流”。 “流式”寫出版本號和大小。 “從流”讀取版本號和大小,加載當前版本和流版本中的每個字段,清除剩余的,然后從流中讀取剩余的數據。

如果發現需要更高的性能,您會注意到,汽車的位置和角度的變化比齒輪的變化要頻繁得多。 另外,丟棄在現有幀之間合理插值的幀會大大減小重放格式的大小(根據您的描述,這並不意味着您正在重放中運行物理)。 最后,如果您具有一致的物理模型,則只能存儲用戶輸入並基於此輸入進行重放(但這很難實現)。

其他缺點:只需在有問題的結構上調用operator=即可替換SRECORDASSIGN。 0x4C這樣的魔術數字應用於指針都是很愚蠢的,並且幾乎總是可以用簡單的結構成員訪問來替換。

如果我正確地解釋了您的問題(很累,那么如果我錯了,請發表評論),您想在文件之間來回記錄。

可以使用任何結構輕松完成此操作:

struct Foo
{
   float bar;
   int baz;
};
std::ostream& operator<<(std::ostream& stream, const Foo &foo)
{
   stream << foo.bar << " " << foo.baz;
}
std::ofstream& operator<<(std::ofstream& stream, Foo &foo)
{
   stream.write(reinterpret_cast<char*>(&foo.bar), sizeof(bar));
   stream.write(reinterpret_cast<char*>(&foo.baz), sizeof(baz));
}
std::ifstream& operator>>(std::ifstream& stream, Foo &foo)
{
   stream.read(reinterpret_cast<char*>(&foo.bar), sizeof(bar));
   stream.read(reinterpret_cast<char*>(&foo.baz), sizeof(baz));
}

您可以使用

#include <fstream>
#include <iostream>

int main()
{
   Foo foo;
   foo.bar = -1.2f;
   foo.baz = 37;
    std::cout << foo << "\n";
   std::ofstream output;
   output.open("myfile", std::ios::binary);
   output << foo;
   output.close();
   std::ifstream input;
   input.open("myfile", std::ios::binary);
   input >> foo;
   input.close();
   std::cout << foo << "\n";
}

有關std::basic_ostream::writestd::basic::istream::read ,建議您訪問cppreference.com。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM