Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在c++;(RAM,硬盘驱动器,冷)_C++_File_Pointers_Filesystems_Boost_Boost Filesystem - Fatal编程技术网

C++ 如何在c++;(RAM,硬盘驱动器,冷)

C++ 如何在c++;(RAM,硬盘驱动器,冷),c++,file,pointers,filesystems,boost,boost-filesystem,C++,File,Pointers,Filesystems,Boost,Boost Filesystem,我有一个简单的POD数据类,比如 struct hash{ char buffer[16]; }; 我需要有一个向量,它的许多实例将Shorely不适合ram(20 PB)。它在概念上被分组为一个向量(树)。我想有一种方法可以让指针式的东西隐藏RAM、文件系统、冷存储,并有一个简单的数组\指针式接口(使fs、初始化后的操作不可见,但允许它有多个位置来放置数据-RAM、快速SSD、SSD、HDD、磁带、云驱动器位置) 如何在C++中进行这样的事情? 在语言层面上没有支持。 一种解决方案是

我有一个简单的POD数据类,比如

struct hash{
    char buffer[16];
};
我需要有一个向量,它的许多实例将Shorely不适合ram(20 PB)。它在概念上被分组为一个向量(树)。我想有一种方法可以让指针式的东西隐藏RAM、文件系统、冷存储,并有一个简单的数组\指针式接口(使fs、初始化后的操作不可见,但允许它有多个位置来放置数据-RAM、快速SSD、SSD、HDD、磁带、云驱动器位置)


<>如何在C++中进行这样的事情?

在语言层面上没有支持。

一种解决方案是使用内存映射文件,例如,请参见:

如果您需要一个更独立于平台的解决方案,那么您可以使用对库中的内存映射文件也有一定支持的解决方案

除此之外,您还可以创建一个类似指针的对象外观来管理底层逻辑(如智能指针)

模板
结构MyMappedPointerType{
T&operator*MyPointerType();//解除防护-可能引发。。
//实现语义的其余部分
};

我想通常会使用一些手柄。然后,当您想要访问对象时,您将把句柄传递给一个函数,该函数将加载内存并给您地址,然后关闭句柄。在C++中,你会使用RAII. < /P>
#include <string>
#include <cstdio>

template <class T>
class Access
{
private:
    FILE* f= nullptr;
public:
    Access(const std::string& filename)
    {
        f= fopen(filename.data(), "rw");
    }

    ~Access()
    {
        fclose(f);
    }

    class WriteAccess
    {
        T buffer{};
        bool dirty= false;
        FILE* f;
        int64_t elementNumber;
    public:
        WriteAccess(FILE* f, int64_t elementNumber)
        : f(f)
        , elementNumber(elementNumber)
        {
            if (f) {
                fseek(f, elementNumber*sizeof(buffer), SEEK_SET);
                fread(&buffer, sizeof(buffer), 1, f);
            }
        }

        T& get() { dirty= true; return buffer; }
        const T& get() const { return buffer; }

        ~WriteAccess()
        {
            if (dirty && f) {
                fseek(f, elementNumber*sizeof(buffer), SEEK_SET);
                fwrite(&buffer, sizeof(buffer), 1, f);
            }
        }
    };

    WriteAccess operator[] (int64_t elementNumber)
    {
        return WriteAccess(f, elementNumber);
    }
};

struct SomeData
{
    int a= 0;
    int b= 0;
    int c= 0;
};

int main()
{
    Access<SomeData> myfile("thedata.bin");

    myfile[0].get().a= 1;
    auto pos1= myfile[1];

    pos1.get().a= 10;
    pos1.get().b= 10;
}
#包括
#包括
模板
类访问
{
私人:
FILE*f=nullptr;
公众:
访问(常量std::字符串和文件名)
{
f=fopen(filename.data(),“rw”);
}
~Access()
{
fclose(f);
}
类WriteAccess
{
T缓冲区{};
bool dirty=false;
文件*f;
int64_t元素编号;
公众:
WriteAccess(文件*f,int64\u t元素编号)
:f(f)
,elementNumber(elementNumber)
{
如果(f){
fseek(f,elementNumber*sizeof(buffer),SEEK_SET);
fread(&buffer,sizeof(buffer),1,f);
}
}
T&get(){dirty=true;返回缓冲区;}
const T&get()const{return buffer;}
~WriteAccess()
{
如果(脏的(&f){
fseek(f,elementNumber*sizeof(buffer),SEEK_SET);
fwrite(&buffer,sizeof(buffer),1,f);
}
}
};
WriteAccess运算符[](int64_t elementNumber)
{
返回写访问(f,元素编号);
}
};
结构某些数据
{
int a=0;
int b=0;
int c=0;
};
int main()
{
访问我的文件(“thedata.bin”);
myfile[0].get().a=1;
auto pos1=myfile[1];
pos1.get().a=10;
pos1.get().b=10;
}

当然,您可以提供读访问和写访问,可能不使用FOpenD,但新的C++文件,您应该检查错误< /强>,并且您可以以转换运算符的形式将<代码> GET()/<代码>函数转换为<代码> t<代码> >

您还应该注意,您可以使用一些ref计数,在我的简单示例中,
Access
class应该比
WriteAccess
class更有效

此外,如果这将被多个线程使用,您应该锁定,我假设您不会两次访问同一个元素


或者你也可以使用内存映射文件访问,就像他们告诉你的一样。

C和C++的答案完全不同,但总体思路是,你必须在缓存层之间实现一个接口,然后实现每个层。你的钥匙是什么样子的?它也是16字节的原始数据吗?你想做的是非常广泛的,而且一点也不琐碎,尽管希望这能为你指明正确的方向:@David:是的is@J.:我的错-没有明确说明数组是可调整大小的(向量)建议:您可能对
#include <string>
#include <cstdio>

template <class T>
class Access
{
private:
    FILE* f= nullptr;
public:
    Access(const std::string& filename)
    {
        f= fopen(filename.data(), "rw");
    }

    ~Access()
    {
        fclose(f);
    }

    class WriteAccess
    {
        T buffer{};
        bool dirty= false;
        FILE* f;
        int64_t elementNumber;
    public:
        WriteAccess(FILE* f, int64_t elementNumber)
        : f(f)
        , elementNumber(elementNumber)
        {
            if (f) {
                fseek(f, elementNumber*sizeof(buffer), SEEK_SET);
                fread(&buffer, sizeof(buffer), 1, f);
            }
        }

        T& get() { dirty= true; return buffer; }
        const T& get() const { return buffer; }

        ~WriteAccess()
        {
            if (dirty && f) {
                fseek(f, elementNumber*sizeof(buffer), SEEK_SET);
                fwrite(&buffer, sizeof(buffer), 1, f);
            }
        }
    };

    WriteAccess operator[] (int64_t elementNumber)
    {
        return WriteAccess(f, elementNumber);
    }
};

struct SomeData
{
    int a= 0;
    int b= 0;
    int c= 0;
};

int main()
{
    Access<SomeData> myfile("thedata.bin");

    myfile[0].get().a= 1;
    auto pos1= myfile[1];

    pos1.get().a= 10;
    pos1.get().b= 10;
}