为大文件创建mmap(要读取的3D数组)

时间:2018-01-30 09:03:52

标签: c++ multidimensional-array mmap

我必须读取一个包含1300张320 * 256 uint16像素的图像的二进制文件,并将其转换为3D数组。数据以little-endian mod保存,所以我在char中读取2个字节并将其转换为double(以后用它做一些操作)。保存的数据采用以下模式:

Main header / Frame header1 / Frame1 / Frame header2  / Frame2 / etc.

抱歉,我无法给你这个档案。我的实际C ++代码是:

编辑:新版本需要4秒而不是21

#include "stdafx.h"
#include <iostream>
#include "stdio.h"
#include <fstream>
#include <stdint.h>

using namespace std;

// Create a function to convert any size of data in little-endian mod
template<class T>
T my_ntoh_little(unsigned char* buf) {
    const auto s = sizeof(T);
    T value = 0;
    for (unsigned i = 0; i < s; i++)
        value |= buf[i] << CHAR_BIT * i;
    return value;
}

int main()
{
    ifstream is("Filename", ifstream::binary);
    if (is) {
        // Create 3D array to stock images
        unsigned char data_char[2];
        double ***data;
        data = new double**[1299];
        for (unsigned i = 0; i < 1299; i++) {
            data[i] = new double*[256];
            for (unsigned j = 0; j < 256; j++)
                data[i][j] = new double[320];
        }

        // Pass main header
        is.seekg(3000, is.beg);

        // Read all data once
        is.read(reinterpret_cast<char*>(data_char), length);

        // Convert pixel by pixel from uchar to double
        int buffer_image = width * height * 2;
        int indice;

        for (unsigned count = 0; count < count_frames; count++) {
            indice = main_header_size + count * (frame_header_size + buffer_image) + frame_header_size;
            for (unsigned i = 0; i < 256; i++){
                for (unsigned j = 0; j < 320; j++) {
                    data[count][i][j] = my_ntoh_little<uint16_t>(data_char + indice);
                    indice += 2;
                }
            }
        }

        // De-Allocate memory to prevent memory leak
        for (int i = 0; i < 1299; ++i) {
            for (int j = 0; j < 256; ++j)
                delete[] data[i][j];

            delete[] data[i];
        }
        delete[] data;

    }
    return 0;
}

我已经在Python中创建了一个内存映射来读取这个文件但是在C ++中我找不到如何实现这个目标。我尝试这样做是因为现在我需要21秒才能读取非常长的文件。我知道在Python中,使用内存映射的读数不到0.1秒。我正在寻找一个等价的解决方案,比我的实际速度要快得多。

Code Python:

dt = [('headers', np.void, frame_header_size), ('frames', '<u2', (height, width))]
mmap = np.memmap(nom_fichier, dt, offset=main_header_size)
array2 = mmap['frames']

我提前感谢您的任何建议/帮助。

0 个答案:

没有答案