topguntoo 2023-04-11 17:11 采纳率: 40%
浏览 71
已结题

MFC 二进制文件数据管理

我要采集大约0-100条曲线数据,每采集一条在列表上显示出来,方便查询删除等管理,请问所采集的曲线如果用 fstream 二进制方式存储的话,能否存储在一个文件里?每条曲线坐标点数在500到1000个坐标点的样子,长短不一要如何读写呢?如果不能存到一个二进制文件里,那就是一条曲线 一个文件 那如何管理这些二进制文件呢?

  • 写回答

11条回答 默认 最新

  • 「已注销」 2023-04-11 18:56
    关注

    引用new bing作答:
    三个问题的回答分别如下:
    1 可以将所有的曲线数据存储到同一个二进制文件中,只需要在文件中规定好每条曲线的数据格式和长度,以便读取时能够准确地分离出每条曲线的数据。
    以下是一个简单的示例代码来演示如何存储和读取二进制文件中的多条曲线数据。

    存储多条曲线数据到同一个二进制文件中:

    #include <iostream>
    #include <fstream>
    #include <vector>
    
    using namespace std;
    
    struct Point {
        float x;
        float y;
    };
    
    struct Curve {
        vector<Point> points;
    };
    
    void WriteCurvesToFile(const vector<Curve>& curves, const char* filename) {
        ofstream out(filename, ios::binary);
        if (out) {
            // 写入曲线数量
            int num_curves = curves.size();
            out.write(reinterpret_cast<char*>(&num_curves), sizeof(int));
    
            // 写入每条曲线的数据
            for (const auto& curve : curves) {
                // 写入曲线长度
                int num_points = curve.points.size();
                out.write(reinterpret_cast<char*>(&num_points), sizeof(int));
    
                // 写入曲线数据
                out.write(reinterpret_cast<char*>(curve.points.data()), sizeof(Point) * num_points);
            }
    
            out.close();
        }
    }
    
    int main() {
        vector<Curve> curves = {
            {{ {0, 0}, {1, 1}, {2, 4} }},
            {{ {0, 0}, {1, 2}, {2, 6} }},
            {{ {0, 0}, {1, 3}, {2, 9} }}
        };
    
        WriteCurvesToFile(curves, "curves.bin");
    
        return 0;
    }
    

    2 对于不同长度的曲线数据,可以采用同一种数据格式进行存储,例如在文件中先存储曲线的总点数,再依次存储每个点的 x 坐标和 y 坐标,这样读取时可以先读取总点数,再根据总点数读取每个点的坐标信息。
    读取同一个二进制文件中的多条曲线数据:

    #include <iostream>
    #include <fstream>
    #include <vector>
    
    using namespace std;
    
    struct Point {
        float x;
        float y;
    };
    
    struct Curve {
        vector<Point> points;
    };
    
    vector<Curve> ReadCurvesFromFile(const char* filename) {
        vector<Curve> curves;
    
        ifstream in(filename, ios::binary);
        if (in) {
            // 读取曲线数量
            int num_curves = 0;
            in.read(reinterpret_cast<char*>(&num_curves), sizeof(int));
    
            // 读取每条曲线的数据
            for (int i = 0; i < num_curves; i++) {
                Curve curve;
    
                // 读取曲线长度
                int num_points = 0;
                in.read(reinterpret_cast<char*>(&num_points), sizeof(int));
    
                // 读取曲线数据
                for (int j = 0; j < num_points; j++) {
                    Point p;
                    in.read(reinterpret_cast<char*>(&p), sizeof(Point));
                    curve.points.push_back(p);
                }
    
                curves.push_back(curve);
            }
    
            in.close();
        }
    
        return curves;
    }
    
    int main() {
        vector<Curve> curves = ReadCurvesFromFile("curves.bin");
    
        // 输出读取到的曲线数据
        for (const auto& curve : curves) {
            for (const auto& point : curve.points) {
                cout << "(" << point.x << ", " << point.y << ") ";
            }
            cout << endl;
        }
    
        return 0;
    }
    

    3 如果每条曲线存储到一个文件中,可以采用文件名与曲线编号对应的方式来管理这些二进制文件,例如第一条曲线对应的文件名为"curve_1.bin",第二条曲线对应的文件名为"curve_2.bin",以此类推。这样可以方便地进行查询和删除操作。另外,为了避免过多的文件占用系统资源,可以考虑定期清理一些不再需要的曲线文件。
    存储每条曲线数据到一个单独的二进制文件中:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <sstream>
    
    using namespace std;
    
    struct Point {
        float x;
        float y;
    };
    
    struct Curve {
        vector<Point> points;
    };
    
    void WriteCurveToFile(const Curve& curve, const char* filename) {
        ofstream out(filename, ios::binary);
        if (out) {
            // 写入曲线长度
            int num_points = curve.points.size();
            out.write(reinterpret_cast<char*>(&num_points), sizeof(int));
    
            // 写入曲线数据
            out.write(reinterpret_cast<char*>(curve.points.data()), sizeof(Point) * num_points);
    
            out.close();
        }
    }
    
    Curve ReadCurveFromFile(const char* filename) {
        Curve curve;
    
        ifstream in(filename, ios::binary);
        if (in) {
            // 读取曲线长度
            int num_points = 0;
            in.read(reinterpret_cast<char*>(&num_points), sizeof(int));
    
            // 读取曲线数据
            for (int j = 0; j < num_points; j++) {
                Point p;
                in.read(reinterpret_cast<char*>(&p), sizeof(Point));
                curve.points.push_back(p);
            }
    
            in.close();
        }
    
        return curve;
    }
    
    string GetCurveFilename(int index) {
        stringstream ss;
        ss << "curve_" << index << ".bin";
        return ss.str();
    }
    
    int main() {
        vector<Curve> curves = {
            {{ {0, 0}, {1, 1}, {2, 4} }},
            {{ {0, 0}, {1, 2}, {2, 6} }},
            {{ {0, 0}, {1, 3}, {2, 9} }}
        };
    
        // 存储每条曲线到单独的文件中
        for (int i = 0; i < curves.size(); i++) {
            WriteCurveToFile(curves[i], GetCurveFilename(i).c_str());
        }
    
        // 读取每条曲线文件并输出数据
        for (int i = 0; i < curves.size(); i++) {
            Curve curve = ReadCurveFromFile(GetCurveFilename(i).c_str());
    
            // 输出读取到的曲线数据
            for (const auto& point : curve.points) {
                cout << "(" << point.x << ", " << point.y << ") ";
            }
            cout << endl;
        }
    
        return 0;
    }
    

    在这个示例代码中,我们定义了两个函数 WriteCurveToFile 和 ReadCurveFromFile,用于将一条曲线数据存储到单独的二进制文件中,以及从二进制文件中读取一条曲线数据。我们还定义了一个函数 GetCurveFilename,用于生成每条曲线的文件名。

    在主函数中,我们先将每条曲线数据存储到单独的二进制文件中,然后读取每条曲线文件并输出数据。

    评论

报告相同问题?

问题事件

  • 系统已结题 4月19日
  • 赞助了问题酬金15元 4月11日
  • 创建了问题 4月11日